diff options
145 files changed, 16778 insertions, 8226 deletions
diff --git a/pkg/abi/linux/linux_abi_autogen_unsafe.go b/pkg/abi/linux/linux_abi_autogen_unsafe.go index 285e270b7..868b27001 100644 --- a/pkg/abi/linux/linux_abi_autogen_unsafe.go +++ b/pkg/abi/linux/linux_abi_autogen_unsafe.go @@ -138,7 +138,7 @@ func (s *Statx) MarshalUnsafe(dst []byte) { // UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe. func (s *Statx) UnmarshalUnsafe(src []byte) { - if s.Atime.Packed() && s.Btime.Packed() && s.Ctime.Packed() && s.Mtime.Packed() { + if s.Ctime.Packed() && s.Mtime.Packed() && s.Atime.Packed() && s.Btime.Packed() { safecopy.CopyOut(unsafe.Pointer(s), src) } else { s.UnmarshalBytes(src) @@ -178,7 +178,7 @@ func (s *Statx) CopyOut(task marshal.Task, addr usermem.Addr) (int, error) { // CopyIn implements marshal.Marshallable.CopyIn. //go:nosplit func (s *Statx) CopyIn(task marshal.Task, addr usermem.Addr) (int, error) { - if !s.Btime.Packed() && s.Ctime.Packed() && s.Mtime.Packed() && s.Atime.Packed() { + if !s.Atime.Packed() && s.Btime.Packed() && s.Ctime.Packed() && s.Mtime.Packed() { // Type Statx doesn't have a packed layout in memory, fall back to UnmarshalBytes. buf := task.CopyScratchBuffer(s.SizeBytes()) // escapes: okay. length, err := task.CopyInBytes(addr, buf) // escapes: okay. diff --git a/pkg/abi/linux/linux_amd64_state_autogen.go b/pkg/abi/linux/linux_amd64_state_autogen.go index 58cabce4c..474bb3e65 100644 --- a/pkg/abi/linux/linux_amd64_state_autogen.go +++ b/pkg/abi/linux/linux_amd64_state_autogen.go @@ -11,69 +11,107 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *PtraceRegs) StateTypeName() string { + return "pkg/abi/linux.PtraceRegs" +} + +func (x *PtraceRegs) StateFields() []string { + return []string{ + "R15", + "R14", + "R13", + "R12", + "Rbp", + "Rbx", + "R11", + "R10", + "R9", + "R8", + "Rax", + "Rcx", + "Rdx", + "Rsi", + "Rdi", + "Orig_rax", + "Rip", + "Cs", + "Eflags", + "Rsp", + "Ss", + "Fs_base", + "Gs_base", + "Ds", + "Es", + "Fs", + "Gs", + } +} + func (x *PtraceRegs) beforeSave() {} -func (x *PtraceRegs) save(m state.Map) { + +func (x *PtraceRegs) StateSave(m state.Sink) { x.beforeSave() - m.Save("R15", &x.R15) - m.Save("R14", &x.R14) - m.Save("R13", &x.R13) - m.Save("R12", &x.R12) - m.Save("Rbp", &x.Rbp) - m.Save("Rbx", &x.Rbx) - m.Save("R11", &x.R11) - m.Save("R10", &x.R10) - m.Save("R9", &x.R9) - m.Save("R8", &x.R8) - m.Save("Rax", &x.Rax) - m.Save("Rcx", &x.Rcx) - m.Save("Rdx", &x.Rdx) - m.Save("Rsi", &x.Rsi) - m.Save("Rdi", &x.Rdi) - m.Save("Orig_rax", &x.Orig_rax) - m.Save("Rip", &x.Rip) - m.Save("Cs", &x.Cs) - m.Save("Eflags", &x.Eflags) - m.Save("Rsp", &x.Rsp) - m.Save("Ss", &x.Ss) - m.Save("Fs_base", &x.Fs_base) - m.Save("Gs_base", &x.Gs_base) - m.Save("Ds", &x.Ds) - m.Save("Es", &x.Es) - m.Save("Fs", &x.Fs) - m.Save("Gs", &x.Gs) + m.Save(0, &x.R15) + m.Save(1, &x.R14) + m.Save(2, &x.R13) + m.Save(3, &x.R12) + m.Save(4, &x.Rbp) + m.Save(5, &x.Rbx) + m.Save(6, &x.R11) + m.Save(7, &x.R10) + m.Save(8, &x.R9) + m.Save(9, &x.R8) + m.Save(10, &x.Rax) + m.Save(11, &x.Rcx) + m.Save(12, &x.Rdx) + m.Save(13, &x.Rsi) + m.Save(14, &x.Rdi) + m.Save(15, &x.Orig_rax) + m.Save(16, &x.Rip) + m.Save(17, &x.Cs) + m.Save(18, &x.Eflags) + m.Save(19, &x.Rsp) + m.Save(20, &x.Ss) + m.Save(21, &x.Fs_base) + m.Save(22, &x.Gs_base) + m.Save(23, &x.Ds) + m.Save(24, &x.Es) + m.Save(25, &x.Fs) + m.Save(26, &x.Gs) } func (x *PtraceRegs) afterLoad() {} -func (x *PtraceRegs) load(m state.Map) { - m.Load("R15", &x.R15) - m.Load("R14", &x.R14) - m.Load("R13", &x.R13) - m.Load("R12", &x.R12) - m.Load("Rbp", &x.Rbp) - m.Load("Rbx", &x.Rbx) - m.Load("R11", &x.R11) - m.Load("R10", &x.R10) - m.Load("R9", &x.R9) - m.Load("R8", &x.R8) - m.Load("Rax", &x.Rax) - m.Load("Rcx", &x.Rcx) - m.Load("Rdx", &x.Rdx) - m.Load("Rsi", &x.Rsi) - m.Load("Rdi", &x.Rdi) - m.Load("Orig_rax", &x.Orig_rax) - m.Load("Rip", &x.Rip) - m.Load("Cs", &x.Cs) - m.Load("Eflags", &x.Eflags) - m.Load("Rsp", &x.Rsp) - m.Load("Ss", &x.Ss) - m.Load("Fs_base", &x.Fs_base) - m.Load("Gs_base", &x.Gs_base) - m.Load("Ds", &x.Ds) - m.Load("Es", &x.Es) - m.Load("Fs", &x.Fs) - m.Load("Gs", &x.Gs) + +func (x *PtraceRegs) StateLoad(m state.Source) { + m.Load(0, &x.R15) + m.Load(1, &x.R14) + m.Load(2, &x.R13) + m.Load(3, &x.R12) + m.Load(4, &x.Rbp) + m.Load(5, &x.Rbx) + m.Load(6, &x.R11) + m.Load(7, &x.R10) + m.Load(8, &x.R9) + m.Load(9, &x.R8) + m.Load(10, &x.Rax) + m.Load(11, &x.Rcx) + m.Load(12, &x.Rdx) + m.Load(13, &x.Rsi) + m.Load(14, &x.Rdi) + m.Load(15, &x.Orig_rax) + m.Load(16, &x.Rip) + m.Load(17, &x.Cs) + m.Load(18, &x.Eflags) + m.Load(19, &x.Rsp) + m.Load(20, &x.Ss) + m.Load(21, &x.Fs_base) + m.Load(22, &x.Gs_base) + m.Load(23, &x.Ds) + m.Load(24, &x.Es) + m.Load(25, &x.Fs) + m.Load(26, &x.Gs) } func init() { - state.Register("pkg/abi/linux.PtraceRegs", (*PtraceRegs)(nil), state.Fns{Save: (*PtraceRegs).save, Load: (*PtraceRegs).load}) + state.Register((*PtraceRegs)(nil)) } diff --git a/pkg/abi/linux/linux_arm64_state_autogen.go b/pkg/abi/linux/linux_arm64_state_autogen.go index 301a5cb76..30c6bef55 100644 --- a/pkg/abi/linux/linux_arm64_state_autogen.go +++ b/pkg/abi/linux/linux_arm64_state_autogen.go @@ -10,23 +10,38 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *PtraceRegs) StateTypeName() string { + return "pkg/abi/linux.PtraceRegs" +} + +func (x *PtraceRegs) StateFields() []string { + return []string{ + "Regs", + "Sp", + "Pc", + "Pstate", + } +} + func (x *PtraceRegs) beforeSave() {} -func (x *PtraceRegs) save(m state.Map) { + +func (x *PtraceRegs) StateSave(m state.Sink) { x.beforeSave() - m.Save("Regs", &x.Regs) - m.Save("Sp", &x.Sp) - m.Save("Pc", &x.Pc) - m.Save("Pstate", &x.Pstate) + m.Save(0, &x.Regs) + m.Save(1, &x.Sp) + m.Save(2, &x.Pc) + m.Save(3, &x.Pstate) } func (x *PtraceRegs) afterLoad() {} -func (x *PtraceRegs) load(m state.Map) { - m.Load("Regs", &x.Regs) - m.Load("Sp", &x.Sp) - m.Load("Pc", &x.Pc) - m.Load("Pstate", &x.Pstate) + +func (x *PtraceRegs) StateLoad(m state.Source) { + m.Load(0, &x.Regs) + m.Load(1, &x.Sp) + m.Load(2, &x.Pc) + m.Load(3, &x.Pstate) } func init() { - state.Register("pkg/abi/linux.PtraceRegs", (*PtraceRegs)(nil), state.Fns{Save: (*PtraceRegs).save, Load: (*PtraceRegs).load}) + state.Register((*PtraceRegs)(nil)) } diff --git a/pkg/abi/linux/linux_state_autogen.go b/pkg/abi/linux/linux_state_autogen.go index 67da4be84..a2bfcd215 100644 --- a/pkg/abi/linux/linux_state_autogen.go +++ b/pkg/abi/linux/linux_state_autogen.go @@ -6,81 +6,143 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *IOEvent) StateTypeName() string { + return "pkg/abi/linux.IOEvent" +} + +func (x *IOEvent) StateFields() []string { + return []string{ + "Data", + "Obj", + "Result", + "Result2", + } +} + func (x *IOEvent) beforeSave() {} -func (x *IOEvent) save(m state.Map) { + +func (x *IOEvent) StateSave(m state.Sink) { x.beforeSave() - m.Save("Data", &x.Data) - m.Save("Obj", &x.Obj) - m.Save("Result", &x.Result) - m.Save("Result2", &x.Result2) + m.Save(0, &x.Data) + m.Save(1, &x.Obj) + m.Save(2, &x.Result) + m.Save(3, &x.Result2) } func (x *IOEvent) afterLoad() {} -func (x *IOEvent) load(m state.Map) { - m.Load("Data", &x.Data) - m.Load("Obj", &x.Obj) - m.Load("Result", &x.Result) - m.Load("Result2", &x.Result2) + +func (x *IOEvent) StateLoad(m state.Source) { + m.Load(0, &x.Data) + m.Load(1, &x.Obj) + m.Load(2, &x.Result) + m.Load(3, &x.Result2) +} + +func (x *BPFInstruction) StateTypeName() string { + return "pkg/abi/linux.BPFInstruction" +} + +func (x *BPFInstruction) StateFields() []string { + return []string{ + "OpCode", + "JumpIfTrue", + "JumpIfFalse", + "K", + } } func (x *BPFInstruction) beforeSave() {} -func (x *BPFInstruction) save(m state.Map) { + +func (x *BPFInstruction) StateSave(m state.Sink) { x.beforeSave() - m.Save("OpCode", &x.OpCode) - m.Save("JumpIfTrue", &x.JumpIfTrue) - m.Save("JumpIfFalse", &x.JumpIfFalse) - m.Save("K", &x.K) + m.Save(0, &x.OpCode) + m.Save(1, &x.JumpIfTrue) + m.Save(2, &x.JumpIfFalse) + m.Save(3, &x.K) } func (x *BPFInstruction) afterLoad() {} -func (x *BPFInstruction) load(m state.Map) { - m.Load("OpCode", &x.OpCode) - m.Load("JumpIfTrue", &x.JumpIfTrue) - m.Load("JumpIfFalse", &x.JumpIfFalse) - m.Load("K", &x.K) + +func (x *BPFInstruction) StateLoad(m state.Source) { + m.Load(0, &x.OpCode) + m.Load(1, &x.JumpIfTrue) + m.Load(2, &x.JumpIfFalse) + m.Load(3, &x.K) +} + +func (x *KernelTermios) StateTypeName() string { + return "pkg/abi/linux.KernelTermios" +} + +func (x *KernelTermios) StateFields() []string { + return []string{ + "InputFlags", + "OutputFlags", + "ControlFlags", + "LocalFlags", + "LineDiscipline", + "ControlCharacters", + "InputSpeed", + "OutputSpeed", + } } func (x *KernelTermios) beforeSave() {} -func (x *KernelTermios) save(m state.Map) { + +func (x *KernelTermios) StateSave(m state.Sink) { x.beforeSave() - m.Save("InputFlags", &x.InputFlags) - m.Save("OutputFlags", &x.OutputFlags) - m.Save("ControlFlags", &x.ControlFlags) - m.Save("LocalFlags", &x.LocalFlags) - m.Save("LineDiscipline", &x.LineDiscipline) - m.Save("ControlCharacters", &x.ControlCharacters) - m.Save("InputSpeed", &x.InputSpeed) - m.Save("OutputSpeed", &x.OutputSpeed) + m.Save(0, &x.InputFlags) + m.Save(1, &x.OutputFlags) + m.Save(2, &x.ControlFlags) + m.Save(3, &x.LocalFlags) + m.Save(4, &x.LineDiscipline) + m.Save(5, &x.ControlCharacters) + m.Save(6, &x.InputSpeed) + m.Save(7, &x.OutputSpeed) } func (x *KernelTermios) afterLoad() {} -func (x *KernelTermios) load(m state.Map) { - m.Load("InputFlags", &x.InputFlags) - m.Load("OutputFlags", &x.OutputFlags) - m.Load("ControlFlags", &x.ControlFlags) - m.Load("LocalFlags", &x.LocalFlags) - m.Load("LineDiscipline", &x.LineDiscipline) - m.Load("ControlCharacters", &x.ControlCharacters) - m.Load("InputSpeed", &x.InputSpeed) - m.Load("OutputSpeed", &x.OutputSpeed) + +func (x *KernelTermios) StateLoad(m state.Source) { + m.Load(0, &x.InputFlags) + m.Load(1, &x.OutputFlags) + m.Load(2, &x.ControlFlags) + m.Load(3, &x.LocalFlags) + m.Load(4, &x.LineDiscipline) + m.Load(5, &x.ControlCharacters) + m.Load(6, &x.InputSpeed) + m.Load(7, &x.OutputSpeed) +} + +func (x *WindowSize) StateTypeName() string { + return "pkg/abi/linux.WindowSize" +} + +func (x *WindowSize) StateFields() []string { + return []string{ + "Rows", + "Cols", + } } func (x *WindowSize) beforeSave() {} -func (x *WindowSize) save(m state.Map) { + +func (x *WindowSize) StateSave(m state.Sink) { x.beforeSave() - m.Save("Rows", &x.Rows) - m.Save("Cols", &x.Cols) + m.Save(0, &x.Rows) + m.Save(1, &x.Cols) } func (x *WindowSize) afterLoad() {} -func (x *WindowSize) load(m state.Map) { - m.Load("Rows", &x.Rows) - m.Load("Cols", &x.Cols) + +func (x *WindowSize) StateLoad(m state.Source) { + m.Load(0, &x.Rows) + m.Load(1, &x.Cols) } func init() { - state.Register("pkg/abi/linux.IOEvent", (*IOEvent)(nil), state.Fns{Save: (*IOEvent).save, Load: (*IOEvent).load}) - state.Register("pkg/abi/linux.BPFInstruction", (*BPFInstruction)(nil), state.Fns{Save: (*BPFInstruction).save, Load: (*BPFInstruction).load}) - state.Register("pkg/abi/linux.KernelTermios", (*KernelTermios)(nil), state.Fns{Save: (*KernelTermios).save, Load: (*KernelTermios).load}) - state.Register("pkg/abi/linux.WindowSize", (*WindowSize)(nil), state.Fns{Save: (*WindowSize).save, Load: (*WindowSize).load}) + state.Register((*IOEvent)(nil)) + state.Register((*BPFInstruction)(nil)) + state.Register((*KernelTermios)(nil)) + state.Register((*WindowSize)(nil)) } diff --git a/pkg/bpf/bpf_state_autogen.go b/pkg/bpf/bpf_state_autogen.go index ae8a36d57..43dd9ff9e 100644 --- a/pkg/bpf/bpf_state_autogen.go +++ b/pkg/bpf/bpf_state_autogen.go @@ -6,17 +6,29 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *Program) StateTypeName() string { + return "pkg/bpf.Program" +} + +func (x *Program) StateFields() []string { + return []string{ + "instructions", + } +} + func (x *Program) beforeSave() {} -func (x *Program) save(m state.Map) { + +func (x *Program) StateSave(m state.Sink) { x.beforeSave() - m.Save("instructions", &x.instructions) + m.Save(0, &x.instructions) } func (x *Program) afterLoad() {} -func (x *Program) load(m state.Map) { - m.Load("instructions", &x.instructions) + +func (x *Program) StateLoad(m state.Source) { + m.Load(0, &x.instructions) } func init() { - state.Register("pkg/bpf.Program", (*Program)(nil), state.Fns{Save: (*Program).save, Load: (*Program).load}) + state.Register((*Program)(nil)) } diff --git a/pkg/buffer/buffer_list.go b/pkg/buffer/buffer_list.go index 15c7a74cc..891ea961a 100644 --- a/pkg/buffer/buffer_list.go +++ b/pkg/buffer/buffer_list.go @@ -56,7 +56,7 @@ func (l *bufferList) Back() *buffer { // // NOTE: This is an O(n) operation. func (l *bufferList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (bufferElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *bufferList) Remove(e *buffer) { if prev != nil { bufferElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { bufferElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/buffer/buffer_state_autogen.go b/pkg/buffer/buffer_state_autogen.go index 2e6299f81..33887cb66 100644 --- a/pkg/buffer/buffer_state_autogen.go +++ b/pkg/buffer/buffer_state_autogen.go @@ -6,65 +6,119 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *buffer) StateTypeName() string { + return "pkg/buffer.buffer" +} + +func (x *buffer) StateFields() []string { + return []string{ + "data", + "read", + "write", + "bufferEntry", + } +} + func (x *buffer) beforeSave() {} -func (x *buffer) save(m state.Map) { + +func (x *buffer) StateSave(m state.Sink) { x.beforeSave() - m.Save("data", &x.data) - m.Save("read", &x.read) - m.Save("write", &x.write) - m.Save("bufferEntry", &x.bufferEntry) + m.Save(0, &x.data) + m.Save(1, &x.read) + m.Save(2, &x.write) + m.Save(3, &x.bufferEntry) } func (x *buffer) afterLoad() {} -func (x *buffer) load(m state.Map) { - m.Load("data", &x.data) - m.Load("read", &x.read) - m.Load("write", &x.write) - m.Load("bufferEntry", &x.bufferEntry) + +func (x *buffer) StateLoad(m state.Source) { + m.Load(0, &x.data) + m.Load(1, &x.read) + m.Load(2, &x.write) + m.Load(3, &x.bufferEntry) +} + +func (x *bufferList) StateTypeName() string { + return "pkg/buffer.bufferList" +} + +func (x *bufferList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *bufferList) beforeSave() {} -func (x *bufferList) save(m state.Map) { + +func (x *bufferList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *bufferList) afterLoad() {} -func (x *bufferList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *bufferList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *bufferEntry) StateTypeName() string { + return "pkg/buffer.bufferEntry" +} + +func (x *bufferEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *bufferEntry) beforeSave() {} -func (x *bufferEntry) save(m state.Map) { + +func (x *bufferEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *bufferEntry) afterLoad() {} -func (x *bufferEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *bufferEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) +} + +func (x *View) StateTypeName() string { + return "pkg/buffer.View" +} + +func (x *View) StateFields() []string { + return []string{ + "data", + "size", + } } func (x *View) beforeSave() {} -func (x *View) save(m state.Map) { + +func (x *View) StateSave(m state.Sink) { x.beforeSave() - m.Save("data", &x.data) - m.Save("size", &x.size) + m.Save(0, &x.data) + m.Save(1, &x.size) } func (x *View) afterLoad() {} -func (x *View) load(m state.Map) { - m.Load("data", &x.data) - m.Load("size", &x.size) + +func (x *View) StateLoad(m state.Source) { + m.Load(0, &x.data) + m.Load(1, &x.size) } func init() { - state.Register("pkg/buffer.buffer", (*buffer)(nil), state.Fns{Save: (*buffer).save, Load: (*buffer).load}) - state.Register("pkg/buffer.bufferList", (*bufferList)(nil), state.Fns{Save: (*bufferList).save, Load: (*bufferList).load}) - state.Register("pkg/buffer.bufferEntry", (*bufferEntry)(nil), state.Fns{Save: (*bufferEntry).save, Load: (*bufferEntry).load}) - state.Register("pkg/buffer.View", (*View)(nil), state.Fns{Save: (*View).save, Load: (*View).load}) + state.Register((*buffer)(nil)) + state.Register((*bufferList)(nil)) + state.Register((*bufferEntry)(nil)) + state.Register((*View)(nil)) } diff --git a/pkg/compressio/compressio.go b/pkg/compressio/compressio.go index 5f52cbe74..b094c5662 100644 --- a/pkg/compressio/compressio.go +++ b/pkg/compressio/compressio.go @@ -346,20 +346,22 @@ func (p *pool) schedule(c *chunk, callback func(*chunk) error) error { } } -// reader chunks reads and decompresses. -type reader struct { +// Reader is a compressed reader. +type Reader struct { pool // in is the source. in io.Reader } +var _ io.Reader = (*Reader)(nil) + // NewReader returns a new compressed reader. If key is non-nil, the data stream // is assumed to contain expected hash values, which will be compared against // hash values computed from the compressed bytes. See package comments for // details. -func NewReader(in io.Reader, key []byte) (io.Reader, error) { - r := &reader{ +func NewReader(in io.Reader, key []byte) (*Reader, error) { + r := &Reader{ in: in, } @@ -394,8 +396,19 @@ var errNewBuffer = errors.New("buffer ready") // ErrHashMismatch is returned if the hash does not match. var ErrHashMismatch = errors.New("hash mismatch") +// ReadByte implements wire.Reader.ReadByte. +func (r *Reader) ReadByte() (byte, error) { + var p [1]byte + n, err := r.Read(p[:]) + if n != 1 { + return p[0], err + } + // Suppress EOF. + return p[0], nil +} + // Read implements io.Reader.Read. -func (r *reader) Read(p []byte) (int, error) { +func (r *Reader) Read(p []byte) (int, error) { r.mu.Lock() defer r.mu.Unlock() @@ -551,8 +564,8 @@ func (r *reader) Read(p []byte) (int, error) { return done, nil } -// writer chunks and schedules writes. -type writer struct { +// Writer is a compressed writer. +type Writer struct { pool // out is the underlying writer. @@ -562,6 +575,8 @@ type writer struct { closed bool } +var _ io.Writer = (*Writer)(nil) + // NewWriter returns a new compressed writer. If key is non-nil, hash values are // generated and written out for compressed bytes. See package comments for // details. @@ -569,8 +584,8 @@ type writer struct { // The recommended chunkSize is on the order of 1M. Extra memory may be // buffered (in the form of read-ahead, or buffered writes), and is limited to // O(chunkSize * [1+GOMAXPROCS]). -func NewWriter(out io.Writer, key []byte, chunkSize uint32, level int) (io.WriteCloser, error) { - w := &writer{ +func NewWriter(out io.Writer, key []byte, chunkSize uint32, level int) (*Writer, error) { + w := &Writer{ pool: pool{ chunkSize: chunkSize, buf: bufPool.Get().(*bytes.Buffer), @@ -597,7 +612,7 @@ func NewWriter(out io.Writer, key []byte, chunkSize uint32, level int) (io.Write } // flush writes a single buffer. -func (w *writer) flush(c *chunk) error { +func (w *Writer) flush(c *chunk) error { // Prefix each chunk with a length; this allows the reader to safely // limit reads while buffering. l := uint32(c.compressed.Len()) @@ -624,8 +639,23 @@ func (w *writer) flush(c *chunk) error { return nil } +// WriteByte implements wire.Writer.WriteByte. +// +// Note that this implementation is necessary on the object itself, as an +// interface-based dispatch cannot tell whether the array backing the slice +// escapes, therefore the all bytes written will generate an escape. +func (w *Writer) WriteByte(b byte) error { + var p [1]byte + p[0] = b + n, err := w.Write(p[:]) + if n != 1 { + return err + } + return nil +} + // Write implements io.Writer.Write. -func (w *writer) Write(p []byte) (int, error) { +func (w *Writer) Write(p []byte) (int, error) { w.mu.Lock() defer w.mu.Unlock() @@ -710,7 +740,7 @@ func (w *writer) Write(p []byte) (int, error) { } // Close implements io.Closer.Close. -func (w *writer) Close() error { +func (w *Writer) Close() error { w.mu.Lock() defer w.mu.Unlock() diff --git a/pkg/cpuid/cpuid_arm64_state_autogen.go b/pkg/cpuid/cpuid_arm64_state_autogen.go index 0e671d441..10569802c 100644 --- a/pkg/cpuid/cpuid_arm64_state_autogen.go +++ b/pkg/cpuid/cpuid_arm64_state_autogen.go @@ -8,27 +8,44 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *FeatureSet) StateTypeName() string { + return "pkg/cpuid.FeatureSet" +} + +func (x *FeatureSet) StateFields() []string { + return []string{ + "Set", + "CPUImplementer", + "CPUArchitecture", + "CPUVariant", + "CPUPartnum", + "CPURevision", + } +} + func (x *FeatureSet) beforeSave() {} -func (x *FeatureSet) save(m state.Map) { + +func (x *FeatureSet) StateSave(m state.Sink) { x.beforeSave() - m.Save("Set", &x.Set) - m.Save("CPUImplementer", &x.CPUImplementer) - m.Save("CPUArchitecture", &x.CPUArchitecture) - m.Save("CPUVariant", &x.CPUVariant) - m.Save("CPUPartnum", &x.CPUPartnum) - m.Save("CPURevision", &x.CPURevision) + m.Save(0, &x.Set) + m.Save(1, &x.CPUImplementer) + m.Save(2, &x.CPUArchitecture) + m.Save(3, &x.CPUVariant) + m.Save(4, &x.CPUPartnum) + m.Save(5, &x.CPURevision) } func (x *FeatureSet) afterLoad() {} -func (x *FeatureSet) load(m state.Map) { - m.Load("Set", &x.Set) - m.Load("CPUImplementer", &x.CPUImplementer) - m.Load("CPUArchitecture", &x.CPUArchitecture) - m.Load("CPUVariant", &x.CPUVariant) - m.Load("CPUPartnum", &x.CPUPartnum) - m.Load("CPURevision", &x.CPURevision) + +func (x *FeatureSet) StateLoad(m state.Source) { + m.Load(0, &x.Set) + m.Load(1, &x.CPUImplementer) + m.Load(2, &x.CPUArchitecture) + m.Load(3, &x.CPUVariant) + m.Load(4, &x.CPUPartnum) + m.Load(5, &x.CPURevision) } func init() { - state.Register("pkg/cpuid.FeatureSet", (*FeatureSet)(nil), state.Fns{Save: (*FeatureSet).save, Load: (*FeatureSet).load}) + state.Register((*FeatureSet)(nil)) } diff --git a/pkg/cpuid/cpuid_x86_state_autogen.go b/pkg/cpuid/cpuid_x86_state_autogen.go index 591868c88..14b26bef7 100644 --- a/pkg/cpuid/cpuid_x86_state_autogen.go +++ b/pkg/cpuid/cpuid_x86_state_autogen.go @@ -8,63 +8,104 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *Cache) StateTypeName() string { + return "pkg/cpuid.Cache" +} + +func (x *Cache) StateFields() []string { + return []string{ + "Level", + "Type", + "FullyAssociative", + "Partitions", + "Ways", + "Sets", + "InvalidateHierarchical", + "Inclusive", + "DirectMapped", + } +} + func (x *Cache) beforeSave() {} -func (x *Cache) save(m state.Map) { + +func (x *Cache) StateSave(m state.Sink) { x.beforeSave() - m.Save("Level", &x.Level) - m.Save("Type", &x.Type) - m.Save("FullyAssociative", &x.FullyAssociative) - m.Save("Partitions", &x.Partitions) - m.Save("Ways", &x.Ways) - m.Save("Sets", &x.Sets) - m.Save("InvalidateHierarchical", &x.InvalidateHierarchical) - m.Save("Inclusive", &x.Inclusive) - m.Save("DirectMapped", &x.DirectMapped) + m.Save(0, &x.Level) + m.Save(1, &x.Type) + m.Save(2, &x.FullyAssociative) + m.Save(3, &x.Partitions) + m.Save(4, &x.Ways) + m.Save(5, &x.Sets) + m.Save(6, &x.InvalidateHierarchical) + m.Save(7, &x.Inclusive) + m.Save(8, &x.DirectMapped) } func (x *Cache) afterLoad() {} -func (x *Cache) load(m state.Map) { - m.Load("Level", &x.Level) - m.Load("Type", &x.Type) - m.Load("FullyAssociative", &x.FullyAssociative) - m.Load("Partitions", &x.Partitions) - m.Load("Ways", &x.Ways) - m.Load("Sets", &x.Sets) - m.Load("InvalidateHierarchical", &x.InvalidateHierarchical) - m.Load("Inclusive", &x.Inclusive) - m.Load("DirectMapped", &x.DirectMapped) + +func (x *Cache) StateLoad(m state.Source) { + m.Load(0, &x.Level) + m.Load(1, &x.Type) + m.Load(2, &x.FullyAssociative) + m.Load(3, &x.Partitions) + m.Load(4, &x.Ways) + m.Load(5, &x.Sets) + m.Load(6, &x.InvalidateHierarchical) + m.Load(7, &x.Inclusive) + m.Load(8, &x.DirectMapped) +} + +func (x *FeatureSet) StateTypeName() string { + return "pkg/cpuid.FeatureSet" +} + +func (x *FeatureSet) StateFields() []string { + return []string{ + "Set", + "VendorID", + "ExtendedFamily", + "ExtendedModel", + "ProcessorType", + "Family", + "Model", + "SteppingID", + "Caches", + "CacheLine", + } } func (x *FeatureSet) beforeSave() {} -func (x *FeatureSet) save(m state.Map) { + +func (x *FeatureSet) StateSave(m state.Sink) { x.beforeSave() - m.Save("Set", &x.Set) - m.Save("VendorID", &x.VendorID) - m.Save("ExtendedFamily", &x.ExtendedFamily) - m.Save("ExtendedModel", &x.ExtendedModel) - m.Save("ProcessorType", &x.ProcessorType) - m.Save("Family", &x.Family) - m.Save("Model", &x.Model) - m.Save("SteppingID", &x.SteppingID) - m.Save("Caches", &x.Caches) - m.Save("CacheLine", &x.CacheLine) + m.Save(0, &x.Set) + m.Save(1, &x.VendorID) + m.Save(2, &x.ExtendedFamily) + m.Save(3, &x.ExtendedModel) + m.Save(4, &x.ProcessorType) + m.Save(5, &x.Family) + m.Save(6, &x.Model) + m.Save(7, &x.SteppingID) + m.Save(8, &x.Caches) + m.Save(9, &x.CacheLine) } func (x *FeatureSet) afterLoad() {} -func (x *FeatureSet) load(m state.Map) { - m.Load("Set", &x.Set) - m.Load("VendorID", &x.VendorID) - m.Load("ExtendedFamily", &x.ExtendedFamily) - m.Load("ExtendedModel", &x.ExtendedModel) - m.Load("ProcessorType", &x.ProcessorType) - m.Load("Family", &x.Family) - m.Load("Model", &x.Model) - m.Load("SteppingID", &x.SteppingID) - m.Load("Caches", &x.Caches) - m.Load("CacheLine", &x.CacheLine) + +func (x *FeatureSet) StateLoad(m state.Source) { + m.Load(0, &x.Set) + m.Load(1, &x.VendorID) + m.Load(2, &x.ExtendedFamily) + m.Load(3, &x.ExtendedModel) + m.Load(4, &x.ProcessorType) + m.Load(5, &x.Family) + m.Load(6, &x.Model) + m.Load(7, &x.SteppingID) + m.Load(8, &x.Caches) + m.Load(9, &x.CacheLine) } func init() { - state.Register("pkg/cpuid.Cache", (*Cache)(nil), state.Fns{Save: (*Cache).save, Load: (*Cache).load}) - state.Register("pkg/cpuid.FeatureSet", (*FeatureSet)(nil), state.Fns{Save: (*FeatureSet).save, Load: (*FeatureSet).load}) + state.Register((*Cache)(nil)) + state.Register((*FeatureSet)(nil)) } diff --git a/pkg/ilist/ilist_state_autogen.go b/pkg/ilist/ilist_state_autogen.go index 4294bcb90..d175c965e 100644 --- a/pkg/ilist/ilist_state_autogen.go +++ b/pkg/ilist/ilist_state_autogen.go @@ -6,33 +6,59 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *List) StateTypeName() string { + return "pkg/ilist.List" +} + +func (x *List) StateFields() []string { + return []string{ + "head", + "tail", + } +} + func (x *List) beforeSave() {} -func (x *List) save(m state.Map) { + +func (x *List) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *List) afterLoad() {} -func (x *List) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *List) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *Entry) StateTypeName() string { + return "pkg/ilist.Entry" +} + +func (x *Entry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *Entry) beforeSave() {} -func (x *Entry) save(m state.Map) { + +func (x *Entry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *Entry) afterLoad() {} -func (x *Entry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *Entry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) } func init() { - state.Register("pkg/ilist.List", (*List)(nil), state.Fns{Save: (*List).save, Load: (*List).load}) - state.Register("pkg/ilist.Entry", (*Entry)(nil), state.Fns{Save: (*Entry).save, Load: (*Entry).load}) + state.Register((*List)(nil)) + state.Register((*Entry)(nil)) } diff --git a/pkg/ilist/interface_list.go b/pkg/ilist/interface_list.go index cabf46e3f..80c655830 100644 --- a/pkg/ilist/interface_list.go +++ b/pkg/ilist/interface_list.go @@ -75,7 +75,7 @@ func (l *List) Back() Element { // // NOTE: This is an O(n) operation. func (l *List) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (ElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -167,13 +167,13 @@ func (l *List) Remove(e Element) { if prev != nil { ElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { ElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/refs/refs_state_autogen.go b/pkg/refs/refs_state_autogen.go index 4c5591d30..53e06c283 100644 --- a/pkg/refs/refs_state_autogen.go +++ b/pkg/refs/refs_state_autogen.go @@ -6,76 +6,141 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *WeakRef) StateTypeName() string { + return "pkg/refs.WeakRef" +} + +func (x *WeakRef) StateFields() []string { + return []string{ + "obj", + "user", + } +} + func (x *WeakRef) beforeSave() {} -func (x *WeakRef) save(m state.Map) { + +func (x *WeakRef) StateSave(m state.Sink) { x.beforeSave() var obj savedReference = x.saveObj() - m.SaveValue("obj", obj) - m.Save("user", &x.user) + m.SaveValue(0, obj) + m.Save(1, &x.user) } func (x *WeakRef) afterLoad() {} -func (x *WeakRef) load(m state.Map) { - m.Load("user", &x.user) - m.LoadValue("obj", new(savedReference), func(y interface{}) { x.loadObj(y.(savedReference)) }) + +func (x *WeakRef) StateLoad(m state.Source) { + m.Load(1, &x.user) + m.LoadValue(0, new(savedReference), func(y interface{}) { x.loadObj(y.(savedReference)) }) +} + +func (x *AtomicRefCount) StateTypeName() string { + return "pkg/refs.AtomicRefCount" +} + +func (x *AtomicRefCount) StateFields() []string { + return []string{ + "refCount", + "name", + "stack", + } } func (x *AtomicRefCount) beforeSave() {} -func (x *AtomicRefCount) save(m state.Map) { + +func (x *AtomicRefCount) StateSave(m state.Sink) { x.beforeSave() - m.Save("refCount", &x.refCount) - m.Save("name", &x.name) - m.Save("stack", &x.stack) + m.Save(0, &x.refCount) + m.Save(1, &x.name) + m.Save(2, &x.stack) } func (x *AtomicRefCount) afterLoad() {} -func (x *AtomicRefCount) load(m state.Map) { - m.Load("refCount", &x.refCount) - m.Load("name", &x.name) - m.Load("stack", &x.stack) + +func (x *AtomicRefCount) StateLoad(m state.Source) { + m.Load(0, &x.refCount) + m.Load(1, &x.name) + m.Load(2, &x.stack) +} + +func (x *savedReference) StateTypeName() string { + return "pkg/refs.savedReference" +} + +func (x *savedReference) StateFields() []string { + return []string{ + "obj", + } } func (x *savedReference) beforeSave() {} -func (x *savedReference) save(m state.Map) { + +func (x *savedReference) StateSave(m state.Sink) { x.beforeSave() - m.Save("obj", &x.obj) + m.Save(0, &x.obj) } func (x *savedReference) afterLoad() {} -func (x *savedReference) load(m state.Map) { - m.Load("obj", &x.obj) + +func (x *savedReference) StateLoad(m state.Source) { + m.Load(0, &x.obj) +} + +func (x *weakRefList) StateTypeName() string { + return "pkg/refs.weakRefList" +} + +func (x *weakRefList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *weakRefList) beforeSave() {} -func (x *weakRefList) save(m state.Map) { + +func (x *weakRefList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *weakRefList) afterLoad() {} -func (x *weakRefList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *weakRefList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *weakRefEntry) StateTypeName() string { + return "pkg/refs.weakRefEntry" +} + +func (x *weakRefEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *weakRefEntry) beforeSave() {} -func (x *weakRefEntry) save(m state.Map) { + +func (x *weakRefEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *weakRefEntry) afterLoad() {} -func (x *weakRefEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *weakRefEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) } func init() { - state.Register("pkg/refs.WeakRef", (*WeakRef)(nil), state.Fns{Save: (*WeakRef).save, Load: (*WeakRef).load}) - state.Register("pkg/refs.AtomicRefCount", (*AtomicRefCount)(nil), state.Fns{Save: (*AtomicRefCount).save, Load: (*AtomicRefCount).load}) - state.Register("pkg/refs.savedReference", (*savedReference)(nil), state.Fns{Save: (*savedReference).save, Load: (*savedReference).load}) - state.Register("pkg/refs.weakRefList", (*weakRefList)(nil), state.Fns{Save: (*weakRefList).save, Load: (*weakRefList).load}) - state.Register("pkg/refs.weakRefEntry", (*weakRefEntry)(nil), state.Fns{Save: (*weakRefEntry).save, Load: (*weakRefEntry).load}) + state.Register((*WeakRef)(nil)) + state.Register((*AtomicRefCount)(nil)) + state.Register((*savedReference)(nil)) + state.Register((*weakRefList)(nil)) + state.Register((*weakRefEntry)(nil)) } diff --git a/pkg/refs/weak_ref_list.go b/pkg/refs/weak_ref_list.go index 90433fb28..31460bfc3 100644 --- a/pkg/refs/weak_ref_list.go +++ b/pkg/refs/weak_ref_list.go @@ -56,7 +56,7 @@ func (l *weakRefList) Back() *WeakRef { // // NOTE: This is an O(n) operation. func (l *weakRefList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (weakRefElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *weakRefList) Remove(e *WeakRef) { if prev != nil { weakRefElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { weakRefElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/arch/arch_amd64_state_autogen.go b/pkg/sentry/arch/arch_amd64_state_autogen.go index 73c523c90..a6afbbb53 100644 --- a/pkg/sentry/arch/arch_amd64_state_autogen.go +++ b/pkg/sentry/arch/arch_amd64_state_autogen.go @@ -10,19 +10,32 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *context64) StateTypeName() string { + return "pkg/sentry/arch.context64" +} + +func (x *context64) StateFields() []string { + return []string{ + "State", + "sigFPState", + } +} + func (x *context64) beforeSave() {} -func (x *context64) save(m state.Map) { + +func (x *context64) StateSave(m state.Sink) { x.beforeSave() - m.Save("State", &x.State) - m.Save("sigFPState", &x.sigFPState) + m.Save(0, &x.State) + m.Save(1, &x.sigFPState) } func (x *context64) afterLoad() {} -func (x *context64) load(m state.Map) { - m.Load("State", &x.State) - m.Load("sigFPState", &x.sigFPState) + +func (x *context64) StateLoad(m state.Source) { + m.Load(0, &x.State) + m.Load(1, &x.sigFPState) } func init() { - state.Register("pkg/sentry/arch.context64", (*context64)(nil), state.Fns{Save: (*context64).save, Load: (*context64).load}) + state.Register((*context64)(nil)) } diff --git a/pkg/sentry/arch/arch_state_autogen.go b/pkg/sentry/arch/arch_state_autogen.go index 82f4d9d73..b29124813 100644 --- a/pkg/sentry/arch/arch_state_autogen.go +++ b/pkg/sentry/arch/arch_state_autogen.go @@ -8,93 +8,167 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *MmapLayout) StateTypeName() string { + return "pkg/sentry/arch.MmapLayout" +} + +func (x *MmapLayout) StateFields() []string { + return []string{ + "MinAddr", + "MaxAddr", + "BottomUpBase", + "TopDownBase", + "DefaultDirection", + "MaxStackRand", + } +} + func (x *MmapLayout) beforeSave() {} -func (x *MmapLayout) save(m state.Map) { + +func (x *MmapLayout) StateSave(m state.Sink) { x.beforeSave() - m.Save("MinAddr", &x.MinAddr) - m.Save("MaxAddr", &x.MaxAddr) - m.Save("BottomUpBase", &x.BottomUpBase) - m.Save("TopDownBase", &x.TopDownBase) - m.Save("DefaultDirection", &x.DefaultDirection) - m.Save("MaxStackRand", &x.MaxStackRand) + m.Save(0, &x.MinAddr) + m.Save(1, &x.MaxAddr) + m.Save(2, &x.BottomUpBase) + m.Save(3, &x.TopDownBase) + m.Save(4, &x.DefaultDirection) + m.Save(5, &x.MaxStackRand) } func (x *MmapLayout) afterLoad() {} -func (x *MmapLayout) load(m state.Map) { - m.Load("MinAddr", &x.MinAddr) - m.Load("MaxAddr", &x.MaxAddr) - m.Load("BottomUpBase", &x.BottomUpBase) - m.Load("TopDownBase", &x.TopDownBase) - m.Load("DefaultDirection", &x.DefaultDirection) - m.Load("MaxStackRand", &x.MaxStackRand) + +func (x *MmapLayout) StateLoad(m state.Source) { + m.Load(0, &x.MinAddr) + m.Load(1, &x.MaxAddr) + m.Load(2, &x.BottomUpBase) + m.Load(3, &x.TopDownBase) + m.Load(4, &x.DefaultDirection) + m.Load(5, &x.MaxStackRand) +} + +func (x *AuxEntry) StateTypeName() string { + return "pkg/sentry/arch.AuxEntry" +} + +func (x *AuxEntry) StateFields() []string { + return []string{ + "Key", + "Value", + } } func (x *AuxEntry) beforeSave() {} -func (x *AuxEntry) save(m state.Map) { + +func (x *AuxEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("Key", &x.Key) - m.Save("Value", &x.Value) + m.Save(0, &x.Key) + m.Save(1, &x.Value) } func (x *AuxEntry) afterLoad() {} -func (x *AuxEntry) load(m state.Map) { - m.Load("Key", &x.Key) - m.Load("Value", &x.Value) + +func (x *AuxEntry) StateLoad(m state.Source) { + m.Load(0, &x.Key) + m.Load(1, &x.Value) +} + +func (x *SignalAct) StateTypeName() string { + return "pkg/sentry/arch.SignalAct" +} + +func (x *SignalAct) StateFields() []string { + return []string{ + "Handler", + "Flags", + "Restorer", + "Mask", + } } func (x *SignalAct) beforeSave() {} -func (x *SignalAct) save(m state.Map) { + +func (x *SignalAct) StateSave(m state.Sink) { x.beforeSave() - m.Save("Handler", &x.Handler) - m.Save("Flags", &x.Flags) - m.Save("Restorer", &x.Restorer) - m.Save("Mask", &x.Mask) + m.Save(0, &x.Handler) + m.Save(1, &x.Flags) + m.Save(2, &x.Restorer) + m.Save(3, &x.Mask) } func (x *SignalAct) afterLoad() {} -func (x *SignalAct) load(m state.Map) { - m.Load("Handler", &x.Handler) - m.Load("Flags", &x.Flags) - m.Load("Restorer", &x.Restorer) - m.Load("Mask", &x.Mask) + +func (x *SignalAct) StateLoad(m state.Source) { + m.Load(0, &x.Handler) + m.Load(1, &x.Flags) + m.Load(2, &x.Restorer) + m.Load(3, &x.Mask) +} + +func (x *SignalStack) StateTypeName() string { + return "pkg/sentry/arch.SignalStack" +} + +func (x *SignalStack) StateFields() []string { + return []string{ + "Addr", + "Flags", + "Size", + } } func (x *SignalStack) beforeSave() {} -func (x *SignalStack) save(m state.Map) { + +func (x *SignalStack) StateSave(m state.Sink) { x.beforeSave() - m.Save("Addr", &x.Addr) - m.Save("Flags", &x.Flags) - m.Save("Size", &x.Size) + m.Save(0, &x.Addr) + m.Save(1, &x.Flags) + m.Save(2, &x.Size) } func (x *SignalStack) afterLoad() {} -func (x *SignalStack) load(m state.Map) { - m.Load("Addr", &x.Addr) - m.Load("Flags", &x.Flags) - m.Load("Size", &x.Size) + +func (x *SignalStack) StateLoad(m state.Source) { + m.Load(0, &x.Addr) + m.Load(1, &x.Flags) + m.Load(2, &x.Size) +} + +func (x *SignalInfo) StateTypeName() string { + return "pkg/sentry/arch.SignalInfo" +} + +func (x *SignalInfo) StateFields() []string { + return []string{ + "Signo", + "Errno", + "Code", + "Fields", + } } func (x *SignalInfo) beforeSave() {} -func (x *SignalInfo) save(m state.Map) { + +func (x *SignalInfo) StateSave(m state.Sink) { x.beforeSave() - m.Save("Signo", &x.Signo) - m.Save("Errno", &x.Errno) - m.Save("Code", &x.Code) - m.Save("Fields", &x.Fields) + m.Save(0, &x.Signo) + m.Save(1, &x.Errno) + m.Save(2, &x.Code) + m.Save(3, &x.Fields) } func (x *SignalInfo) afterLoad() {} -func (x *SignalInfo) load(m state.Map) { - m.Load("Signo", &x.Signo) - m.Load("Errno", &x.Errno) - m.Load("Code", &x.Code) - m.Load("Fields", &x.Fields) + +func (x *SignalInfo) StateLoad(m state.Source) { + m.Load(0, &x.Signo) + m.Load(1, &x.Errno) + m.Load(2, &x.Code) + m.Load(3, &x.Fields) } func init() { - state.Register("pkg/sentry/arch.MmapLayout", (*MmapLayout)(nil), state.Fns{Save: (*MmapLayout).save, Load: (*MmapLayout).load}) - state.Register("pkg/sentry/arch.AuxEntry", (*AuxEntry)(nil), state.Fns{Save: (*AuxEntry).save, Load: (*AuxEntry).load}) - state.Register("pkg/sentry/arch.SignalAct", (*SignalAct)(nil), state.Fns{Save: (*SignalAct).save, Load: (*SignalAct).load}) - state.Register("pkg/sentry/arch.SignalStack", (*SignalStack)(nil), state.Fns{Save: (*SignalStack).save, Load: (*SignalStack).load}) - state.Register("pkg/sentry/arch.SignalInfo", (*SignalInfo)(nil), state.Fns{Save: (*SignalInfo).save, Load: (*SignalInfo).load}) + state.Register((*MmapLayout)(nil)) + state.Register((*AuxEntry)(nil)) + state.Register((*SignalAct)(nil)) + state.Register((*SignalStack)(nil)) + state.Register((*SignalInfo)(nil)) } diff --git a/pkg/sentry/arch/arch_x86_impl_state_autogen.go b/pkg/sentry/arch/arch_x86_impl_state_autogen.go index 7303bb17f..e7738a847 100644 --- a/pkg/sentry/arch/arch_x86_impl_state_autogen.go +++ b/pkg/sentry/arch/arch_x86_impl_state_autogen.go @@ -8,21 +8,34 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *State) StateTypeName() string { + return "pkg/sentry/arch.State" +} + +func (x *State) StateFields() []string { + return []string{ + "Regs", + "x86FPState", + "FeatureSet", + } +} + func (x *State) beforeSave() {} -func (x *State) save(m state.Map) { + +func (x *State) StateSave(m state.Sink) { x.beforeSave() - m.Save("Regs", &x.Regs) - m.Save("x86FPState", &x.x86FPState) - m.Save("FeatureSet", &x.FeatureSet) + m.Save(0, &x.Regs) + m.Save(1, &x.x86FPState) + m.Save(2, &x.FeatureSet) } -func (x *State) load(m state.Map) { - m.Load("Regs", &x.Regs) - m.LoadWait("x86FPState", &x.x86FPState) - m.Load("FeatureSet", &x.FeatureSet) +func (x *State) StateLoad(m state.Source) { + m.Load(0, &x.Regs) + m.LoadWait(1, &x.x86FPState) + m.Load(2, &x.FeatureSet) m.AfterLoad(x.afterLoad) } func init() { - state.Register("pkg/sentry/arch.State", (*State)(nil), state.Fns{Save: (*State).save, Load: (*State).load}) + state.Register((*State)(nil)) } diff --git a/pkg/sentry/device/device_state_autogen.go b/pkg/sentry/device/device_state_autogen.go index dd41a5659..8a28a4be4 100644 --- a/pkg/sentry/device/device_state_autogen.go +++ b/pkg/sentry/device/device_state_autogen.go @@ -6,47 +6,86 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *Registry) StateTypeName() string { + return "pkg/sentry/device.Registry" +} + +func (x *Registry) StateFields() []string { + return []string{ + "lastAnonDeviceMinor", + "devices", + } +} + func (x *Registry) beforeSave() {} -func (x *Registry) save(m state.Map) { + +func (x *Registry) StateSave(m state.Sink) { x.beforeSave() - m.Save("lastAnonDeviceMinor", &x.lastAnonDeviceMinor) - m.Save("devices", &x.devices) + m.Save(0, &x.lastAnonDeviceMinor) + m.Save(1, &x.devices) } func (x *Registry) afterLoad() {} -func (x *Registry) load(m state.Map) { - m.Load("lastAnonDeviceMinor", &x.lastAnonDeviceMinor) - m.Load("devices", &x.devices) + +func (x *Registry) StateLoad(m state.Source) { + m.Load(0, &x.lastAnonDeviceMinor) + m.Load(1, &x.devices) +} + +func (x *ID) StateTypeName() string { + return "pkg/sentry/device.ID" +} + +func (x *ID) StateFields() []string { + return []string{ + "Major", + "Minor", + } } func (x *ID) beforeSave() {} -func (x *ID) save(m state.Map) { + +func (x *ID) StateSave(m state.Sink) { x.beforeSave() - m.Save("Major", &x.Major) - m.Save("Minor", &x.Minor) + m.Save(0, &x.Major) + m.Save(1, &x.Minor) } func (x *ID) afterLoad() {} -func (x *ID) load(m state.Map) { - m.Load("Major", &x.Major) - m.Load("Minor", &x.Minor) + +func (x *ID) StateLoad(m state.Source) { + m.Load(0, &x.Major) + m.Load(1, &x.Minor) +} + +func (x *Device) StateTypeName() string { + return "pkg/sentry/device.Device" +} + +func (x *Device) StateFields() []string { + return []string{ + "ID", + "last", + } } func (x *Device) beforeSave() {} -func (x *Device) save(m state.Map) { + +func (x *Device) StateSave(m state.Sink) { x.beforeSave() - m.Save("ID", &x.ID) - m.Save("last", &x.last) + m.Save(0, &x.ID) + m.Save(1, &x.last) } func (x *Device) afterLoad() {} -func (x *Device) load(m state.Map) { - m.Load("ID", &x.ID) - m.Load("last", &x.last) + +func (x *Device) StateLoad(m state.Source) { + m.Load(0, &x.ID) + m.Load(1, &x.last) } func init() { - state.Register("pkg/sentry/device.Registry", (*Registry)(nil), state.Fns{Save: (*Registry).save, Load: (*Registry).load}) - state.Register("pkg/sentry/device.ID", (*ID)(nil), state.Fns{Save: (*ID).save, Load: (*ID).load}) - state.Register("pkg/sentry/device.Device", (*Device)(nil), state.Fns{Save: (*Device).save, Load: (*Device).load}) + state.Register((*Registry)(nil)) + state.Register((*ID)(nil)) + state.Register((*Device)(nil)) } diff --git a/pkg/sentry/fs/dev/dev_state_autogen.go b/pkg/sentry/fs/dev/dev_state_autogen.go index 272f02672..48a60e45f 100644 --- a/pkg/sentry/fs/dev/dev_state_autogen.go +++ b/pkg/sentry/fs/dev/dev_state_autogen.go @@ -6,149 +6,293 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *filesystem) StateTypeName() string { + return "pkg/sentry/fs/dev.filesystem" +} + +func (x *filesystem) StateFields() []string { + return []string{} +} + func (x *filesystem) beforeSave() {} -func (x *filesystem) save(m state.Map) { + +func (x *filesystem) StateSave(m state.Sink) { x.beforeSave() } func (x *filesystem) afterLoad() {} -func (x *filesystem) load(m state.Map) { + +func (x *filesystem) StateLoad(m state.Source) { +} + +func (x *fullDevice) StateTypeName() string { + return "pkg/sentry/fs/dev.fullDevice" +} + +func (x *fullDevice) StateFields() []string { + return []string{ + "InodeSimpleAttributes", + } } func (x *fullDevice) beforeSave() {} -func (x *fullDevice) save(m state.Map) { + +func (x *fullDevice) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeSimpleAttributes", &x.InodeSimpleAttributes) + m.Save(0, &x.InodeSimpleAttributes) } func (x *fullDevice) afterLoad() {} -func (x *fullDevice) load(m state.Map) { - m.Load("InodeSimpleAttributes", &x.InodeSimpleAttributes) + +func (x *fullDevice) StateLoad(m state.Source) { + m.Load(0, &x.InodeSimpleAttributes) +} + +func (x *fullFileOperations) StateTypeName() string { + return "pkg/sentry/fs/dev.fullFileOperations" +} + +func (x *fullFileOperations) StateFields() []string { + return []string{} } func (x *fullFileOperations) beforeSave() {} -func (x *fullFileOperations) save(m state.Map) { + +func (x *fullFileOperations) StateSave(m state.Sink) { x.beforeSave() } func (x *fullFileOperations) afterLoad() {} -func (x *fullFileOperations) load(m state.Map) { + +func (x *fullFileOperations) StateLoad(m state.Source) { +} + +func (x *netTunInodeOperations) StateTypeName() string { + return "pkg/sentry/fs/dev.netTunInodeOperations" +} + +func (x *netTunInodeOperations) StateFields() []string { + return []string{ + "InodeSimpleAttributes", + } } func (x *netTunInodeOperations) beforeSave() {} -func (x *netTunInodeOperations) save(m state.Map) { + +func (x *netTunInodeOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeSimpleAttributes", &x.InodeSimpleAttributes) + m.Save(0, &x.InodeSimpleAttributes) } func (x *netTunInodeOperations) afterLoad() {} -func (x *netTunInodeOperations) load(m state.Map) { - m.Load("InodeSimpleAttributes", &x.InodeSimpleAttributes) + +func (x *netTunInodeOperations) StateLoad(m state.Source) { + m.Load(0, &x.InodeSimpleAttributes) +} + +func (x *netTunFileOperations) StateTypeName() string { + return "pkg/sentry/fs/dev.netTunFileOperations" +} + +func (x *netTunFileOperations) StateFields() []string { + return []string{ + "device", + } } func (x *netTunFileOperations) beforeSave() {} -func (x *netTunFileOperations) save(m state.Map) { + +func (x *netTunFileOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("device", &x.device) + m.Save(0, &x.device) } func (x *netTunFileOperations) afterLoad() {} -func (x *netTunFileOperations) load(m state.Map) { - m.Load("device", &x.device) + +func (x *netTunFileOperations) StateLoad(m state.Source) { + m.Load(0, &x.device) +} + +func (x *nullDevice) StateTypeName() string { + return "pkg/sentry/fs/dev.nullDevice" +} + +func (x *nullDevice) StateFields() []string { + return []string{ + "InodeSimpleAttributes", + } } func (x *nullDevice) beforeSave() {} -func (x *nullDevice) save(m state.Map) { + +func (x *nullDevice) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeSimpleAttributes", &x.InodeSimpleAttributes) + m.Save(0, &x.InodeSimpleAttributes) } func (x *nullDevice) afterLoad() {} -func (x *nullDevice) load(m state.Map) { - m.Load("InodeSimpleAttributes", &x.InodeSimpleAttributes) + +func (x *nullDevice) StateLoad(m state.Source) { + m.Load(0, &x.InodeSimpleAttributes) +} + +func (x *nullFileOperations) StateTypeName() string { + return "pkg/sentry/fs/dev.nullFileOperations" +} + +func (x *nullFileOperations) StateFields() []string { + return []string{} } func (x *nullFileOperations) beforeSave() {} -func (x *nullFileOperations) save(m state.Map) { + +func (x *nullFileOperations) StateSave(m state.Sink) { x.beforeSave() } func (x *nullFileOperations) afterLoad() {} -func (x *nullFileOperations) load(m state.Map) { + +func (x *nullFileOperations) StateLoad(m state.Source) { +} + +func (x *zeroDevice) StateTypeName() string { + return "pkg/sentry/fs/dev.zeroDevice" +} + +func (x *zeroDevice) StateFields() []string { + return []string{ + "nullDevice", + } } func (x *zeroDevice) beforeSave() {} -func (x *zeroDevice) save(m state.Map) { + +func (x *zeroDevice) StateSave(m state.Sink) { x.beforeSave() - m.Save("nullDevice", &x.nullDevice) + m.Save(0, &x.nullDevice) } func (x *zeroDevice) afterLoad() {} -func (x *zeroDevice) load(m state.Map) { - m.Load("nullDevice", &x.nullDevice) + +func (x *zeroDevice) StateLoad(m state.Source) { + m.Load(0, &x.nullDevice) +} + +func (x *zeroFileOperations) StateTypeName() string { + return "pkg/sentry/fs/dev.zeroFileOperations" +} + +func (x *zeroFileOperations) StateFields() []string { + return []string{} } func (x *zeroFileOperations) beforeSave() {} -func (x *zeroFileOperations) save(m state.Map) { + +func (x *zeroFileOperations) StateSave(m state.Sink) { x.beforeSave() } func (x *zeroFileOperations) afterLoad() {} -func (x *zeroFileOperations) load(m state.Map) { + +func (x *zeroFileOperations) StateLoad(m state.Source) { +} + +func (x *randomDevice) StateTypeName() string { + return "pkg/sentry/fs/dev.randomDevice" +} + +func (x *randomDevice) StateFields() []string { + return []string{ + "InodeSimpleAttributes", + } } func (x *randomDevice) beforeSave() {} -func (x *randomDevice) save(m state.Map) { + +func (x *randomDevice) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeSimpleAttributes", &x.InodeSimpleAttributes) + m.Save(0, &x.InodeSimpleAttributes) } func (x *randomDevice) afterLoad() {} -func (x *randomDevice) load(m state.Map) { - m.Load("InodeSimpleAttributes", &x.InodeSimpleAttributes) + +func (x *randomDevice) StateLoad(m state.Source) { + m.Load(0, &x.InodeSimpleAttributes) +} + +func (x *randomFileOperations) StateTypeName() string { + return "pkg/sentry/fs/dev.randomFileOperations" +} + +func (x *randomFileOperations) StateFields() []string { + return []string{} } func (x *randomFileOperations) beforeSave() {} -func (x *randomFileOperations) save(m state.Map) { + +func (x *randomFileOperations) StateSave(m state.Sink) { x.beforeSave() } func (x *randomFileOperations) afterLoad() {} -func (x *randomFileOperations) load(m state.Map) { + +func (x *randomFileOperations) StateLoad(m state.Source) { +} + +func (x *ttyInodeOperations) StateTypeName() string { + return "pkg/sentry/fs/dev.ttyInodeOperations" +} + +func (x *ttyInodeOperations) StateFields() []string { + return []string{ + "InodeSimpleAttributes", + } } func (x *ttyInodeOperations) beforeSave() {} -func (x *ttyInodeOperations) save(m state.Map) { + +func (x *ttyInodeOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeSimpleAttributes", &x.InodeSimpleAttributes) + m.Save(0, &x.InodeSimpleAttributes) } func (x *ttyInodeOperations) afterLoad() {} -func (x *ttyInodeOperations) load(m state.Map) { - m.Load("InodeSimpleAttributes", &x.InodeSimpleAttributes) + +func (x *ttyInodeOperations) StateLoad(m state.Source) { + m.Load(0, &x.InodeSimpleAttributes) +} + +func (x *ttyFileOperations) StateTypeName() string { + return "pkg/sentry/fs/dev.ttyFileOperations" +} + +func (x *ttyFileOperations) StateFields() []string { + return []string{} } func (x *ttyFileOperations) beforeSave() {} -func (x *ttyFileOperations) save(m state.Map) { + +func (x *ttyFileOperations) StateSave(m state.Sink) { x.beforeSave() } func (x *ttyFileOperations) afterLoad() {} -func (x *ttyFileOperations) load(m state.Map) { + +func (x *ttyFileOperations) StateLoad(m state.Source) { } func init() { - state.Register("pkg/sentry/fs/dev.filesystem", (*filesystem)(nil), state.Fns{Save: (*filesystem).save, Load: (*filesystem).load}) - state.Register("pkg/sentry/fs/dev.fullDevice", (*fullDevice)(nil), state.Fns{Save: (*fullDevice).save, Load: (*fullDevice).load}) - state.Register("pkg/sentry/fs/dev.fullFileOperations", (*fullFileOperations)(nil), state.Fns{Save: (*fullFileOperations).save, Load: (*fullFileOperations).load}) - state.Register("pkg/sentry/fs/dev.netTunInodeOperations", (*netTunInodeOperations)(nil), state.Fns{Save: (*netTunInodeOperations).save, Load: (*netTunInodeOperations).load}) - state.Register("pkg/sentry/fs/dev.netTunFileOperations", (*netTunFileOperations)(nil), state.Fns{Save: (*netTunFileOperations).save, Load: (*netTunFileOperations).load}) - state.Register("pkg/sentry/fs/dev.nullDevice", (*nullDevice)(nil), state.Fns{Save: (*nullDevice).save, Load: (*nullDevice).load}) - state.Register("pkg/sentry/fs/dev.nullFileOperations", (*nullFileOperations)(nil), state.Fns{Save: (*nullFileOperations).save, Load: (*nullFileOperations).load}) - state.Register("pkg/sentry/fs/dev.zeroDevice", (*zeroDevice)(nil), state.Fns{Save: (*zeroDevice).save, Load: (*zeroDevice).load}) - state.Register("pkg/sentry/fs/dev.zeroFileOperations", (*zeroFileOperations)(nil), state.Fns{Save: (*zeroFileOperations).save, Load: (*zeroFileOperations).load}) - state.Register("pkg/sentry/fs/dev.randomDevice", (*randomDevice)(nil), state.Fns{Save: (*randomDevice).save, Load: (*randomDevice).load}) - state.Register("pkg/sentry/fs/dev.randomFileOperations", (*randomFileOperations)(nil), state.Fns{Save: (*randomFileOperations).save, Load: (*randomFileOperations).load}) - state.Register("pkg/sentry/fs/dev.ttyInodeOperations", (*ttyInodeOperations)(nil), state.Fns{Save: (*ttyInodeOperations).save, Load: (*ttyInodeOperations).load}) - state.Register("pkg/sentry/fs/dev.ttyFileOperations", (*ttyFileOperations)(nil), state.Fns{Save: (*ttyFileOperations).save, Load: (*ttyFileOperations).load}) + state.Register((*filesystem)(nil)) + state.Register((*fullDevice)(nil)) + state.Register((*fullFileOperations)(nil)) + state.Register((*netTunInodeOperations)(nil)) + state.Register((*netTunFileOperations)(nil)) + state.Register((*nullDevice)(nil)) + state.Register((*nullFileOperations)(nil)) + state.Register((*zeroDevice)(nil)) + state.Register((*zeroFileOperations)(nil)) + state.Register((*randomDevice)(nil)) + state.Register((*randomFileOperations)(nil)) + state.Register((*ttyInodeOperations)(nil)) + state.Register((*ttyFileOperations)(nil)) } diff --git a/pkg/sentry/fs/dirent_list.go b/pkg/sentry/fs/dirent_list.go index ecbbd7883..357ea925d 100644 --- a/pkg/sentry/fs/dirent_list.go +++ b/pkg/sentry/fs/dirent_list.go @@ -56,7 +56,7 @@ func (l *direntList) Back() *Dirent { // // NOTE: This is an O(n) operation. func (l *direntList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (direntElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *direntList) Remove(e *Dirent) { if prev != nil { direntElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { direntElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/fs/event_list.go b/pkg/sentry/fs/event_list.go index 167fdf906..277d8458e 100644 --- a/pkg/sentry/fs/event_list.go +++ b/pkg/sentry/fs/event_list.go @@ -56,7 +56,7 @@ func (l *eventList) Back() *Event { // // NOTE: This is an O(n) operation. func (l *eventList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (eventElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *eventList) Remove(e *Event) { if prev != nil { eventElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { eventElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/fs/fdpipe/fdpipe_state_autogen.go b/pkg/sentry/fs/fdpipe/fdpipe_state_autogen.go index 9ed7a3d41..359d52e92 100644 --- a/pkg/sentry/fs/fdpipe/fdpipe_state_autogen.go +++ b/pkg/sentry/fs/fdpipe/fdpipe_state_autogen.go @@ -7,21 +7,33 @@ import ( "gvisor.dev/gvisor/pkg/state" ) -func (x *pipeOperations) save(m state.Map) { +func (x *pipeOperations) StateTypeName() string { + return "pkg/sentry/fs/fdpipe.pipeOperations" +} + +func (x *pipeOperations) StateFields() []string { + return []string{ + "flags", + "opener", + "readAheadBuffer", + } +} + +func (x *pipeOperations) StateSave(m state.Sink) { x.beforeSave() var flags fs.FileFlags = x.saveFlags() - m.SaveValue("flags", flags) - m.Save("opener", &x.opener) - m.Save("readAheadBuffer", &x.readAheadBuffer) + m.SaveValue(0, flags) + m.Save(1, &x.opener) + m.Save(2, &x.readAheadBuffer) } -func (x *pipeOperations) load(m state.Map) { - m.LoadWait("opener", &x.opener) - m.Load("readAheadBuffer", &x.readAheadBuffer) - m.LoadValue("flags", new(fs.FileFlags), func(y interface{}) { x.loadFlags(y.(fs.FileFlags)) }) +func (x *pipeOperations) StateLoad(m state.Source) { + m.LoadWait(1, &x.opener) + m.Load(2, &x.readAheadBuffer) + m.LoadValue(0, new(fs.FileFlags), func(y interface{}) { x.loadFlags(y.(fs.FileFlags)) }) m.AfterLoad(x.afterLoad) } func init() { - state.Register("pkg/sentry/fs/fdpipe.pipeOperations", (*pipeOperations)(nil), state.Fns{Save: (*pipeOperations).save, Load: (*pipeOperations).load}) + state.Register((*pipeOperations)(nil)) } diff --git a/pkg/sentry/fs/fs_state_autogen.go b/pkg/sentry/fs/fs_state_autogen.go index 502a90d71..78e30e0e4 100644 --- a/pkg/sentry/fs/fs_state_autogen.go +++ b/pkg/sentry/fs/fs_state_autogen.go @@ -6,633 +6,1136 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *StableAttr) StateTypeName() string { + return "pkg/sentry/fs.StableAttr" +} + +func (x *StableAttr) StateFields() []string { + return []string{ + "Type", + "DeviceID", + "InodeID", + "BlockSize", + "DeviceFileMajor", + "DeviceFileMinor", + } +} + func (x *StableAttr) beforeSave() {} -func (x *StableAttr) save(m state.Map) { + +func (x *StableAttr) StateSave(m state.Sink) { x.beforeSave() - m.Save("Type", &x.Type) - m.Save("DeviceID", &x.DeviceID) - m.Save("InodeID", &x.InodeID) - m.Save("BlockSize", &x.BlockSize) - m.Save("DeviceFileMajor", &x.DeviceFileMajor) - m.Save("DeviceFileMinor", &x.DeviceFileMinor) + m.Save(0, &x.Type) + m.Save(1, &x.DeviceID) + m.Save(2, &x.InodeID) + m.Save(3, &x.BlockSize) + m.Save(4, &x.DeviceFileMajor) + m.Save(5, &x.DeviceFileMinor) } func (x *StableAttr) afterLoad() {} -func (x *StableAttr) load(m state.Map) { - m.Load("Type", &x.Type) - m.Load("DeviceID", &x.DeviceID) - m.Load("InodeID", &x.InodeID) - m.Load("BlockSize", &x.BlockSize) - m.Load("DeviceFileMajor", &x.DeviceFileMajor) - m.Load("DeviceFileMinor", &x.DeviceFileMinor) + +func (x *StableAttr) StateLoad(m state.Source) { + m.Load(0, &x.Type) + m.Load(1, &x.DeviceID) + m.Load(2, &x.InodeID) + m.Load(3, &x.BlockSize) + m.Load(4, &x.DeviceFileMajor) + m.Load(5, &x.DeviceFileMinor) +} + +func (x *UnstableAttr) StateTypeName() string { + return "pkg/sentry/fs.UnstableAttr" +} + +func (x *UnstableAttr) StateFields() []string { + return []string{ + "Size", + "Usage", + "Perms", + "Owner", + "AccessTime", + "ModificationTime", + "StatusChangeTime", + "Links", + } } func (x *UnstableAttr) beforeSave() {} -func (x *UnstableAttr) save(m state.Map) { + +func (x *UnstableAttr) StateSave(m state.Sink) { x.beforeSave() - m.Save("Size", &x.Size) - m.Save("Usage", &x.Usage) - m.Save("Perms", &x.Perms) - m.Save("Owner", &x.Owner) - m.Save("AccessTime", &x.AccessTime) - m.Save("ModificationTime", &x.ModificationTime) - m.Save("StatusChangeTime", &x.StatusChangeTime) - m.Save("Links", &x.Links) + m.Save(0, &x.Size) + m.Save(1, &x.Usage) + m.Save(2, &x.Perms) + m.Save(3, &x.Owner) + m.Save(4, &x.AccessTime) + m.Save(5, &x.ModificationTime) + m.Save(6, &x.StatusChangeTime) + m.Save(7, &x.Links) } func (x *UnstableAttr) afterLoad() {} -func (x *UnstableAttr) load(m state.Map) { - m.Load("Size", &x.Size) - m.Load("Usage", &x.Usage) - m.Load("Perms", &x.Perms) - m.Load("Owner", &x.Owner) - m.Load("AccessTime", &x.AccessTime) - m.Load("ModificationTime", &x.ModificationTime) - m.Load("StatusChangeTime", &x.StatusChangeTime) - m.Load("Links", &x.Links) + +func (x *UnstableAttr) StateLoad(m state.Source) { + m.Load(0, &x.Size) + m.Load(1, &x.Usage) + m.Load(2, &x.Perms) + m.Load(3, &x.Owner) + m.Load(4, &x.AccessTime) + m.Load(5, &x.ModificationTime) + m.Load(6, &x.StatusChangeTime) + m.Load(7, &x.Links) +} + +func (x *AttrMask) StateTypeName() string { + return "pkg/sentry/fs.AttrMask" +} + +func (x *AttrMask) StateFields() []string { + return []string{ + "Type", + "DeviceID", + "InodeID", + "BlockSize", + "Size", + "Usage", + "Perms", + "UID", + "GID", + "AccessTime", + "ModificationTime", + "StatusChangeTime", + "Links", + } } func (x *AttrMask) beforeSave() {} -func (x *AttrMask) save(m state.Map) { - x.beforeSave() - m.Save("Type", &x.Type) - m.Save("DeviceID", &x.DeviceID) - m.Save("InodeID", &x.InodeID) - m.Save("BlockSize", &x.BlockSize) - m.Save("Size", &x.Size) - m.Save("Usage", &x.Usage) - m.Save("Perms", &x.Perms) - m.Save("UID", &x.UID) - m.Save("GID", &x.GID) - m.Save("AccessTime", &x.AccessTime) - m.Save("ModificationTime", &x.ModificationTime) - m.Save("StatusChangeTime", &x.StatusChangeTime) - m.Save("Links", &x.Links) + +func (x *AttrMask) StateSave(m state.Sink) { + x.beforeSave() + m.Save(0, &x.Type) + m.Save(1, &x.DeviceID) + m.Save(2, &x.InodeID) + m.Save(3, &x.BlockSize) + m.Save(4, &x.Size) + m.Save(5, &x.Usage) + m.Save(6, &x.Perms) + m.Save(7, &x.UID) + m.Save(8, &x.GID) + m.Save(9, &x.AccessTime) + m.Save(10, &x.ModificationTime) + m.Save(11, &x.StatusChangeTime) + m.Save(12, &x.Links) } func (x *AttrMask) afterLoad() {} -func (x *AttrMask) load(m state.Map) { - m.Load("Type", &x.Type) - m.Load("DeviceID", &x.DeviceID) - m.Load("InodeID", &x.InodeID) - m.Load("BlockSize", &x.BlockSize) - m.Load("Size", &x.Size) - m.Load("Usage", &x.Usage) - m.Load("Perms", &x.Perms) - m.Load("UID", &x.UID) - m.Load("GID", &x.GID) - m.Load("AccessTime", &x.AccessTime) - m.Load("ModificationTime", &x.ModificationTime) - m.Load("StatusChangeTime", &x.StatusChangeTime) - m.Load("Links", &x.Links) + +func (x *AttrMask) StateLoad(m state.Source) { + m.Load(0, &x.Type) + m.Load(1, &x.DeviceID) + m.Load(2, &x.InodeID) + m.Load(3, &x.BlockSize) + m.Load(4, &x.Size) + m.Load(5, &x.Usage) + m.Load(6, &x.Perms) + m.Load(7, &x.UID) + m.Load(8, &x.GID) + m.Load(9, &x.AccessTime) + m.Load(10, &x.ModificationTime) + m.Load(11, &x.StatusChangeTime) + m.Load(12, &x.Links) +} + +func (x *PermMask) StateTypeName() string { + return "pkg/sentry/fs.PermMask" +} + +func (x *PermMask) StateFields() []string { + return []string{ + "Read", + "Write", + "Execute", + } } func (x *PermMask) beforeSave() {} -func (x *PermMask) save(m state.Map) { + +func (x *PermMask) StateSave(m state.Sink) { x.beforeSave() - m.Save("Read", &x.Read) - m.Save("Write", &x.Write) - m.Save("Execute", &x.Execute) + m.Save(0, &x.Read) + m.Save(1, &x.Write) + m.Save(2, &x.Execute) } func (x *PermMask) afterLoad() {} -func (x *PermMask) load(m state.Map) { - m.Load("Read", &x.Read) - m.Load("Write", &x.Write) - m.Load("Execute", &x.Execute) + +func (x *PermMask) StateLoad(m state.Source) { + m.Load(0, &x.Read) + m.Load(1, &x.Write) + m.Load(2, &x.Execute) +} + +func (x *FilePermissions) StateTypeName() string { + return "pkg/sentry/fs.FilePermissions" +} + +func (x *FilePermissions) StateFields() []string { + return []string{ + "User", + "Group", + "Other", + "Sticky", + "SetUID", + "SetGID", + } } func (x *FilePermissions) beforeSave() {} -func (x *FilePermissions) save(m state.Map) { + +func (x *FilePermissions) StateSave(m state.Sink) { x.beforeSave() - m.Save("User", &x.User) - m.Save("Group", &x.Group) - m.Save("Other", &x.Other) - m.Save("Sticky", &x.Sticky) - m.Save("SetUID", &x.SetUID) - m.Save("SetGID", &x.SetGID) + m.Save(0, &x.User) + m.Save(1, &x.Group) + m.Save(2, &x.Other) + m.Save(3, &x.Sticky) + m.Save(4, &x.SetUID) + m.Save(5, &x.SetGID) } func (x *FilePermissions) afterLoad() {} -func (x *FilePermissions) load(m state.Map) { - m.Load("User", &x.User) - m.Load("Group", &x.Group) - m.Load("Other", &x.Other) - m.Load("Sticky", &x.Sticky) - m.Load("SetUID", &x.SetUID) - m.Load("SetGID", &x.SetGID) + +func (x *FilePermissions) StateLoad(m state.Source) { + m.Load(0, &x.User) + m.Load(1, &x.Group) + m.Load(2, &x.Other) + m.Load(3, &x.Sticky) + m.Load(4, &x.SetUID) + m.Load(5, &x.SetGID) +} + +func (x *FileOwner) StateTypeName() string { + return "pkg/sentry/fs.FileOwner" +} + +func (x *FileOwner) StateFields() []string { + return []string{ + "UID", + "GID", + } } func (x *FileOwner) beforeSave() {} -func (x *FileOwner) save(m state.Map) { + +func (x *FileOwner) StateSave(m state.Sink) { x.beforeSave() - m.Save("UID", &x.UID) - m.Save("GID", &x.GID) + m.Save(0, &x.UID) + m.Save(1, &x.GID) } func (x *FileOwner) afterLoad() {} -func (x *FileOwner) load(m state.Map) { - m.Load("UID", &x.UID) - m.Load("GID", &x.GID) + +func (x *FileOwner) StateLoad(m state.Source) { + m.Load(0, &x.UID) + m.Load(1, &x.GID) +} + +func (x *DentAttr) StateTypeName() string { + return "pkg/sentry/fs.DentAttr" +} + +func (x *DentAttr) StateFields() []string { + return []string{ + "Type", + "InodeID", + } } func (x *DentAttr) beforeSave() {} -func (x *DentAttr) save(m state.Map) { + +func (x *DentAttr) StateSave(m state.Sink) { x.beforeSave() - m.Save("Type", &x.Type) - m.Save("InodeID", &x.InodeID) + m.Save(0, &x.Type) + m.Save(1, &x.InodeID) } func (x *DentAttr) afterLoad() {} -func (x *DentAttr) load(m state.Map) { - m.Load("Type", &x.Type) - m.Load("InodeID", &x.InodeID) + +func (x *DentAttr) StateLoad(m state.Source) { + m.Load(0, &x.Type) + m.Load(1, &x.InodeID) +} + +func (x *SortedDentryMap) StateTypeName() string { + return "pkg/sentry/fs.SortedDentryMap" +} + +func (x *SortedDentryMap) StateFields() []string { + return []string{ + "names", + "entries", + } } func (x *SortedDentryMap) beforeSave() {} -func (x *SortedDentryMap) save(m state.Map) { + +func (x *SortedDentryMap) StateSave(m state.Sink) { x.beforeSave() - m.Save("names", &x.names) - m.Save("entries", &x.entries) + m.Save(0, &x.names) + m.Save(1, &x.entries) } func (x *SortedDentryMap) afterLoad() {} -func (x *SortedDentryMap) load(m state.Map) { - m.Load("names", &x.names) - m.Load("entries", &x.entries) + +func (x *SortedDentryMap) StateLoad(m state.Source) { + m.Load(0, &x.names) + m.Load(1, &x.entries) } -func (x *Dirent) save(m state.Map) { +func (x *Dirent) StateTypeName() string { + return "pkg/sentry/fs.Dirent" +} + +func (x *Dirent) StateFields() []string { + return []string{ + "AtomicRefCount", + "userVisible", + "Inode", + "name", + "parent", + "deleted", + "mounted", + "children", + } +} + +func (x *Dirent) StateSave(m state.Sink) { x.beforeSave() var children map[string]*Dirent = x.saveChildren() - m.SaveValue("children", children) - m.Save("AtomicRefCount", &x.AtomicRefCount) - m.Save("userVisible", &x.userVisible) - m.Save("Inode", &x.Inode) - m.Save("name", &x.name) - m.Save("parent", &x.parent) - m.Save("deleted", &x.deleted) - m.Save("mounted", &x.mounted) -} - -func (x *Dirent) load(m state.Map) { - m.Load("AtomicRefCount", &x.AtomicRefCount) - m.Load("userVisible", &x.userVisible) - m.Load("Inode", &x.Inode) - m.Load("name", &x.name) - m.Load("parent", &x.parent) - m.Load("deleted", &x.deleted) - m.Load("mounted", &x.mounted) - m.LoadValue("children", new(map[string]*Dirent), func(y interface{}) { x.loadChildren(y.(map[string]*Dirent)) }) + m.SaveValue(7, children) + m.Save(0, &x.AtomicRefCount) + m.Save(1, &x.userVisible) + m.Save(2, &x.Inode) + m.Save(3, &x.name) + m.Save(4, &x.parent) + m.Save(5, &x.deleted) + m.Save(6, &x.mounted) +} + +func (x *Dirent) StateLoad(m state.Source) { + m.Load(0, &x.AtomicRefCount) + m.Load(1, &x.userVisible) + m.Load(2, &x.Inode) + m.Load(3, &x.name) + m.Load(4, &x.parent) + m.Load(5, &x.deleted) + m.Load(6, &x.mounted) + m.LoadValue(7, new(map[string]*Dirent), func(y interface{}) { x.loadChildren(y.(map[string]*Dirent)) }) m.AfterLoad(x.afterLoad) } +func (x *DirentCache) StateTypeName() string { + return "pkg/sentry/fs.DirentCache" +} + +func (x *DirentCache) StateFields() []string { + return []string{ + "maxSize", + "limit", + } +} + func (x *DirentCache) beforeSave() {} -func (x *DirentCache) save(m state.Map) { + +func (x *DirentCache) StateSave(m state.Sink) { x.beforeSave() if !state.IsZeroValue(&x.currentSize) { - m.Failf("currentSize is %#v, expected zero", &x.currentSize) + state.Failf("currentSize is %#v, expected zero", &x.currentSize) } if !state.IsZeroValue(&x.list) { - m.Failf("list is %#v, expected zero", &x.list) + state.Failf("list is %#v, expected zero", &x.list) } - m.Save("maxSize", &x.maxSize) - m.Save("limit", &x.limit) + m.Save(0, &x.maxSize) + m.Save(1, &x.limit) } func (x *DirentCache) afterLoad() {} -func (x *DirentCache) load(m state.Map) { - m.Load("maxSize", &x.maxSize) - m.Load("limit", &x.limit) + +func (x *DirentCache) StateLoad(m state.Source) { + m.Load(0, &x.maxSize) + m.Load(1, &x.limit) +} + +func (x *DirentCacheLimiter) StateTypeName() string { + return "pkg/sentry/fs.DirentCacheLimiter" +} + +func (x *DirentCacheLimiter) StateFields() []string { + return []string{ + "max", + } } func (x *DirentCacheLimiter) beforeSave() {} -func (x *DirentCacheLimiter) save(m state.Map) { + +func (x *DirentCacheLimiter) StateSave(m state.Sink) { x.beforeSave() if !state.IsZeroValue(&x.count) { - m.Failf("count is %#v, expected zero", &x.count) + state.Failf("count is %#v, expected zero", &x.count) } - m.Save("max", &x.max) + m.Save(0, &x.max) } func (x *DirentCacheLimiter) afterLoad() {} -func (x *DirentCacheLimiter) load(m state.Map) { - m.Load("max", &x.max) + +func (x *DirentCacheLimiter) StateLoad(m state.Source) { + m.Load(0, &x.max) +} + +func (x *direntList) StateTypeName() string { + return "pkg/sentry/fs.direntList" +} + +func (x *direntList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *direntList) beforeSave() {} -func (x *direntList) save(m state.Map) { + +func (x *direntList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *direntList) afterLoad() {} -func (x *direntList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *direntList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *direntEntry) StateTypeName() string { + return "pkg/sentry/fs.direntEntry" +} + +func (x *direntEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *direntEntry) beforeSave() {} -func (x *direntEntry) save(m state.Map) { + +func (x *direntEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *direntEntry) afterLoad() {} -func (x *direntEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *direntEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) +} + +func (x *eventList) StateTypeName() string { + return "pkg/sentry/fs.eventList" +} + +func (x *eventList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *eventList) beforeSave() {} -func (x *eventList) save(m state.Map) { + +func (x *eventList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *eventList) afterLoad() {} -func (x *eventList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *eventList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *eventEntry) StateTypeName() string { + return "pkg/sentry/fs.eventEntry" +} + +func (x *eventEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *eventEntry) beforeSave() {} -func (x *eventEntry) save(m state.Map) { + +func (x *eventEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *eventEntry) afterLoad() {} -func (x *eventEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) -} - -func (x *File) save(m state.Map) { - x.beforeSave() - m.Save("AtomicRefCount", &x.AtomicRefCount) - m.Save("UniqueID", &x.UniqueID) - m.Save("Dirent", &x.Dirent) - m.Save("flags", &x.flags) - m.Save("async", &x.async) - m.Save("FileOperations", &x.FileOperations) - m.Save("offset", &x.offset) -} - -func (x *File) load(m state.Map) { - m.Load("AtomicRefCount", &x.AtomicRefCount) - m.Load("UniqueID", &x.UniqueID) - m.Load("Dirent", &x.Dirent) - m.Load("flags", &x.flags) - m.Load("async", &x.async) - m.LoadWait("FileOperations", &x.FileOperations) - m.Load("offset", &x.offset) + +func (x *eventEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) +} + +func (x *File) StateTypeName() string { + return "pkg/sentry/fs.File" +} + +func (x *File) StateFields() []string { + return []string{ + "AtomicRefCount", + "UniqueID", + "Dirent", + "flags", + "async", + "FileOperations", + "offset", + } +} + +func (x *File) StateSave(m state.Sink) { + x.beforeSave() + m.Save(0, &x.AtomicRefCount) + m.Save(1, &x.UniqueID) + m.Save(2, &x.Dirent) + m.Save(3, &x.flags) + m.Save(4, &x.async) + m.Save(5, &x.FileOperations) + m.Save(6, &x.offset) +} + +func (x *File) StateLoad(m state.Source) { + m.Load(0, &x.AtomicRefCount) + m.Load(1, &x.UniqueID) + m.Load(2, &x.Dirent) + m.Load(3, &x.flags) + m.Load(4, &x.async) + m.LoadWait(5, &x.FileOperations) + m.Load(6, &x.offset) m.AfterLoad(x.afterLoad) } +func (x *overlayFileOperations) StateTypeName() string { + return "pkg/sentry/fs.overlayFileOperations" +} + +func (x *overlayFileOperations) StateFields() []string { + return []string{ + "upper", + "lower", + "dirCursor", + } +} + func (x *overlayFileOperations) beforeSave() {} -func (x *overlayFileOperations) save(m state.Map) { + +func (x *overlayFileOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("upper", &x.upper) - m.Save("lower", &x.lower) - m.Save("dirCursor", &x.dirCursor) + m.Save(0, &x.upper) + m.Save(1, &x.lower) + m.Save(2, &x.dirCursor) } func (x *overlayFileOperations) afterLoad() {} -func (x *overlayFileOperations) load(m state.Map) { - m.Load("upper", &x.upper) - m.Load("lower", &x.lower) - m.Load("dirCursor", &x.dirCursor) + +func (x *overlayFileOperations) StateLoad(m state.Source) { + m.Load(0, &x.upper) + m.Load(1, &x.lower) + m.Load(2, &x.dirCursor) +} + +func (x *overlayMappingIdentity) StateTypeName() string { + return "pkg/sentry/fs.overlayMappingIdentity" +} + +func (x *overlayMappingIdentity) StateFields() []string { + return []string{ + "AtomicRefCount", + "id", + "overlayFile", + } } func (x *overlayMappingIdentity) beforeSave() {} -func (x *overlayMappingIdentity) save(m state.Map) { + +func (x *overlayMappingIdentity) StateSave(m state.Sink) { x.beforeSave() - m.Save("AtomicRefCount", &x.AtomicRefCount) - m.Save("id", &x.id) - m.Save("overlayFile", &x.overlayFile) + m.Save(0, &x.AtomicRefCount) + m.Save(1, &x.id) + m.Save(2, &x.overlayFile) } func (x *overlayMappingIdentity) afterLoad() {} -func (x *overlayMappingIdentity) load(m state.Map) { - m.Load("AtomicRefCount", &x.AtomicRefCount) - m.Load("id", &x.id) - m.Load("overlayFile", &x.overlayFile) + +func (x *overlayMappingIdentity) StateLoad(m state.Source) { + m.Load(0, &x.AtomicRefCount) + m.Load(1, &x.id) + m.Load(2, &x.overlayFile) +} + +func (x *MountSourceFlags) StateTypeName() string { + return "pkg/sentry/fs.MountSourceFlags" +} + +func (x *MountSourceFlags) StateFields() []string { + return []string{ + "ReadOnly", + "NoAtime", + "ForcePageCache", + "NoExec", + } } func (x *MountSourceFlags) beforeSave() {} -func (x *MountSourceFlags) save(m state.Map) { + +func (x *MountSourceFlags) StateSave(m state.Sink) { x.beforeSave() - m.Save("ReadOnly", &x.ReadOnly) - m.Save("NoAtime", &x.NoAtime) - m.Save("ForcePageCache", &x.ForcePageCache) - m.Save("NoExec", &x.NoExec) + m.Save(0, &x.ReadOnly) + m.Save(1, &x.NoAtime) + m.Save(2, &x.ForcePageCache) + m.Save(3, &x.NoExec) } func (x *MountSourceFlags) afterLoad() {} -func (x *MountSourceFlags) load(m state.Map) { - m.Load("ReadOnly", &x.ReadOnly) - m.Load("NoAtime", &x.NoAtime) - m.Load("ForcePageCache", &x.ForcePageCache) - m.Load("NoExec", &x.NoExec) + +func (x *MountSourceFlags) StateLoad(m state.Source) { + m.Load(0, &x.ReadOnly) + m.Load(1, &x.NoAtime) + m.Load(2, &x.ForcePageCache) + m.Load(3, &x.NoExec) +} + +func (x *FileFlags) StateTypeName() string { + return "pkg/sentry/fs.FileFlags" +} + +func (x *FileFlags) StateFields() []string { + return []string{ + "Direct", + "NonBlocking", + "DSync", + "Sync", + "Append", + "Read", + "Write", + "Pread", + "Pwrite", + "Directory", + "Async", + "LargeFile", + "NonSeekable", + "Truncate", + } } func (x *FileFlags) beforeSave() {} -func (x *FileFlags) save(m state.Map) { - x.beforeSave() - m.Save("Direct", &x.Direct) - m.Save("NonBlocking", &x.NonBlocking) - m.Save("DSync", &x.DSync) - m.Save("Sync", &x.Sync) - m.Save("Append", &x.Append) - m.Save("Read", &x.Read) - m.Save("Write", &x.Write) - m.Save("Pread", &x.Pread) - m.Save("Pwrite", &x.Pwrite) - m.Save("Directory", &x.Directory) - m.Save("Async", &x.Async) - m.Save("LargeFile", &x.LargeFile) - m.Save("NonSeekable", &x.NonSeekable) - m.Save("Truncate", &x.Truncate) + +func (x *FileFlags) StateSave(m state.Sink) { + x.beforeSave() + m.Save(0, &x.Direct) + m.Save(1, &x.NonBlocking) + m.Save(2, &x.DSync) + m.Save(3, &x.Sync) + m.Save(4, &x.Append) + m.Save(5, &x.Read) + m.Save(6, &x.Write) + m.Save(7, &x.Pread) + m.Save(8, &x.Pwrite) + m.Save(9, &x.Directory) + m.Save(10, &x.Async) + m.Save(11, &x.LargeFile) + m.Save(12, &x.NonSeekable) + m.Save(13, &x.Truncate) } func (x *FileFlags) afterLoad() {} -func (x *FileFlags) load(m state.Map) { - m.Load("Direct", &x.Direct) - m.Load("NonBlocking", &x.NonBlocking) - m.Load("DSync", &x.DSync) - m.Load("Sync", &x.Sync) - m.Load("Append", &x.Append) - m.Load("Read", &x.Read) - m.Load("Write", &x.Write) - m.Load("Pread", &x.Pread) - m.Load("Pwrite", &x.Pwrite) - m.Load("Directory", &x.Directory) - m.Load("Async", &x.Async) - m.Load("LargeFile", &x.LargeFile) - m.Load("NonSeekable", &x.NonSeekable) - m.Load("Truncate", &x.Truncate) + +func (x *FileFlags) StateLoad(m state.Source) { + m.Load(0, &x.Direct) + m.Load(1, &x.NonBlocking) + m.Load(2, &x.DSync) + m.Load(3, &x.Sync) + m.Load(4, &x.Append) + m.Load(5, &x.Read) + m.Load(6, &x.Write) + m.Load(7, &x.Pread) + m.Load(8, &x.Pwrite) + m.Load(9, &x.Directory) + m.Load(10, &x.Async) + m.Load(11, &x.LargeFile) + m.Load(12, &x.NonSeekable) + m.Load(13, &x.Truncate) +} + +func (x *Inode) StateTypeName() string { + return "pkg/sentry/fs.Inode" +} + +func (x *Inode) StateFields() []string { + return []string{ + "AtomicRefCount", + "InodeOperations", + "StableAttr", + "LockCtx", + "Watches", + "MountSource", + "overlay", + } } func (x *Inode) beforeSave() {} -func (x *Inode) save(m state.Map) { + +func (x *Inode) StateSave(m state.Sink) { x.beforeSave() - m.Save("AtomicRefCount", &x.AtomicRefCount) - m.Save("InodeOperations", &x.InodeOperations) - m.Save("StableAttr", &x.StableAttr) - m.Save("LockCtx", &x.LockCtx) - m.Save("Watches", &x.Watches) - m.Save("MountSource", &x.MountSource) - m.Save("overlay", &x.overlay) + m.Save(0, &x.AtomicRefCount) + m.Save(1, &x.InodeOperations) + m.Save(2, &x.StableAttr) + m.Save(3, &x.LockCtx) + m.Save(4, &x.Watches) + m.Save(5, &x.MountSource) + m.Save(6, &x.overlay) } func (x *Inode) afterLoad() {} -func (x *Inode) load(m state.Map) { - m.Load("AtomicRefCount", &x.AtomicRefCount) - m.Load("InodeOperations", &x.InodeOperations) - m.Load("StableAttr", &x.StableAttr) - m.Load("LockCtx", &x.LockCtx) - m.Load("Watches", &x.Watches) - m.Load("MountSource", &x.MountSource) - m.Load("overlay", &x.overlay) + +func (x *Inode) StateLoad(m state.Source) { + m.Load(0, &x.AtomicRefCount) + m.Load(1, &x.InodeOperations) + m.Load(2, &x.StableAttr) + m.Load(3, &x.LockCtx) + m.Load(4, &x.Watches) + m.Load(5, &x.MountSource) + m.Load(6, &x.overlay) +} + +func (x *LockCtx) StateTypeName() string { + return "pkg/sentry/fs.LockCtx" +} + +func (x *LockCtx) StateFields() []string { + return []string{ + "Posix", + "BSD", + } } func (x *LockCtx) beforeSave() {} -func (x *LockCtx) save(m state.Map) { + +func (x *LockCtx) StateSave(m state.Sink) { x.beforeSave() - m.Save("Posix", &x.Posix) - m.Save("BSD", &x.BSD) + m.Save(0, &x.Posix) + m.Save(1, &x.BSD) } func (x *LockCtx) afterLoad() {} -func (x *LockCtx) load(m state.Map) { - m.Load("Posix", &x.Posix) - m.Load("BSD", &x.BSD) + +func (x *LockCtx) StateLoad(m state.Source) { + m.Load(0, &x.Posix) + m.Load(1, &x.BSD) +} + +func (x *Watches) StateTypeName() string { + return "pkg/sentry/fs.Watches" +} + +func (x *Watches) StateFields() []string { + return []string{ + "ws", + "unlinked", + } } func (x *Watches) beforeSave() {} -func (x *Watches) save(m state.Map) { + +func (x *Watches) StateSave(m state.Sink) { x.beforeSave() - m.Save("ws", &x.ws) - m.Save("unlinked", &x.unlinked) + m.Save(0, &x.ws) + m.Save(1, &x.unlinked) } func (x *Watches) afterLoad() {} -func (x *Watches) load(m state.Map) { - m.Load("ws", &x.ws) - m.Load("unlinked", &x.unlinked) + +func (x *Watches) StateLoad(m state.Source) { + m.Load(0, &x.ws) + m.Load(1, &x.unlinked) +} + +func (x *Inotify) StateTypeName() string { + return "pkg/sentry/fs.Inotify" +} + +func (x *Inotify) StateFields() []string { + return []string{ + "id", + "events", + "scratch", + "nextWatch", + "watches", + } } func (x *Inotify) beforeSave() {} -func (x *Inotify) save(m state.Map) { + +func (x *Inotify) StateSave(m state.Sink) { x.beforeSave() - m.Save("id", &x.id) - m.Save("events", &x.events) - m.Save("scratch", &x.scratch) - m.Save("nextWatch", &x.nextWatch) - m.Save("watches", &x.watches) + m.Save(0, &x.id) + m.Save(1, &x.events) + m.Save(2, &x.scratch) + m.Save(3, &x.nextWatch) + m.Save(4, &x.watches) } func (x *Inotify) afterLoad() {} -func (x *Inotify) load(m state.Map) { - m.Load("id", &x.id) - m.Load("events", &x.events) - m.Load("scratch", &x.scratch) - m.Load("nextWatch", &x.nextWatch) - m.Load("watches", &x.watches) + +func (x *Inotify) StateLoad(m state.Source) { + m.Load(0, &x.id) + m.Load(1, &x.events) + m.Load(2, &x.scratch) + m.Load(3, &x.nextWatch) + m.Load(4, &x.watches) +} + +func (x *Event) StateTypeName() string { + return "pkg/sentry/fs.Event" +} + +func (x *Event) StateFields() []string { + return []string{ + "eventEntry", + "wd", + "mask", + "cookie", + "len", + "name", + } } func (x *Event) beforeSave() {} -func (x *Event) save(m state.Map) { + +func (x *Event) StateSave(m state.Sink) { x.beforeSave() - m.Save("eventEntry", &x.eventEntry) - m.Save("wd", &x.wd) - m.Save("mask", &x.mask) - m.Save("cookie", &x.cookie) - m.Save("len", &x.len) - m.Save("name", &x.name) + m.Save(0, &x.eventEntry) + m.Save(1, &x.wd) + m.Save(2, &x.mask) + m.Save(3, &x.cookie) + m.Save(4, &x.len) + m.Save(5, &x.name) } func (x *Event) afterLoad() {} -func (x *Event) load(m state.Map) { - m.Load("eventEntry", &x.eventEntry) - m.Load("wd", &x.wd) - m.Load("mask", &x.mask) - m.Load("cookie", &x.cookie) - m.Load("len", &x.len) - m.Load("name", &x.name) + +func (x *Event) StateLoad(m state.Source) { + m.Load(0, &x.eventEntry) + m.Load(1, &x.wd) + m.Load(2, &x.mask) + m.Load(3, &x.cookie) + m.Load(4, &x.len) + m.Load(5, &x.name) +} + +func (x *Watch) StateTypeName() string { + return "pkg/sentry/fs.Watch" +} + +func (x *Watch) StateFields() []string { + return []string{ + "owner", + "wd", + "target", + "unpinned", + "mask", + "pins", + } } func (x *Watch) beforeSave() {} -func (x *Watch) save(m state.Map) { + +func (x *Watch) StateSave(m state.Sink) { x.beforeSave() - m.Save("owner", &x.owner) - m.Save("wd", &x.wd) - m.Save("target", &x.target) - m.Save("unpinned", &x.unpinned) - m.Save("mask", &x.mask) - m.Save("pins", &x.pins) + m.Save(0, &x.owner) + m.Save(1, &x.wd) + m.Save(2, &x.target) + m.Save(3, &x.unpinned) + m.Save(4, &x.mask) + m.Save(5, &x.pins) } func (x *Watch) afterLoad() {} -func (x *Watch) load(m state.Map) { - m.Load("owner", &x.owner) - m.Load("wd", &x.wd) - m.Load("target", &x.target) - m.Load("unpinned", &x.unpinned) - m.Load("mask", &x.mask) - m.Load("pins", &x.pins) + +func (x *Watch) StateLoad(m state.Source) { + m.Load(0, &x.owner) + m.Load(1, &x.wd) + m.Load(2, &x.target) + m.Load(3, &x.unpinned) + m.Load(4, &x.mask) + m.Load(5, &x.pins) +} + +func (x *MountSource) StateTypeName() string { + return "pkg/sentry/fs.MountSource" +} + +func (x *MountSource) StateFields() []string { + return []string{ + "AtomicRefCount", + "MountSourceOperations", + "FilesystemType", + "Flags", + "fscache", + "direntRefs", + } } func (x *MountSource) beforeSave() {} -func (x *MountSource) save(m state.Map) { + +func (x *MountSource) StateSave(m state.Sink) { x.beforeSave() - m.Save("AtomicRefCount", &x.AtomicRefCount) - m.Save("MountSourceOperations", &x.MountSourceOperations) - m.Save("FilesystemType", &x.FilesystemType) - m.Save("Flags", &x.Flags) - m.Save("fscache", &x.fscache) - m.Save("direntRefs", &x.direntRefs) + m.Save(0, &x.AtomicRefCount) + m.Save(1, &x.MountSourceOperations) + m.Save(2, &x.FilesystemType) + m.Save(3, &x.Flags) + m.Save(4, &x.fscache) + m.Save(5, &x.direntRefs) } func (x *MountSource) afterLoad() {} -func (x *MountSource) load(m state.Map) { - m.Load("AtomicRefCount", &x.AtomicRefCount) - m.Load("MountSourceOperations", &x.MountSourceOperations) - m.Load("FilesystemType", &x.FilesystemType) - m.Load("Flags", &x.Flags) - m.Load("fscache", &x.fscache) - m.Load("direntRefs", &x.direntRefs) + +func (x *MountSource) StateLoad(m state.Source) { + m.Load(0, &x.AtomicRefCount) + m.Load(1, &x.MountSourceOperations) + m.Load(2, &x.FilesystemType) + m.Load(3, &x.Flags) + m.Load(4, &x.fscache) + m.Load(5, &x.direntRefs) +} + +func (x *SimpleMountSourceOperations) StateTypeName() string { + return "pkg/sentry/fs.SimpleMountSourceOperations" +} + +func (x *SimpleMountSourceOperations) StateFields() []string { + return []string{ + "keep", + "revalidate", + "cacheReaddir", + } } func (x *SimpleMountSourceOperations) beforeSave() {} -func (x *SimpleMountSourceOperations) save(m state.Map) { + +func (x *SimpleMountSourceOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("keep", &x.keep) - m.Save("revalidate", &x.revalidate) - m.Save("cacheReaddir", &x.cacheReaddir) + m.Save(0, &x.keep) + m.Save(1, &x.revalidate) + m.Save(2, &x.cacheReaddir) } func (x *SimpleMountSourceOperations) afterLoad() {} -func (x *SimpleMountSourceOperations) load(m state.Map) { - m.Load("keep", &x.keep) - m.Load("revalidate", &x.revalidate) - m.Load("cacheReaddir", &x.cacheReaddir) + +func (x *SimpleMountSourceOperations) StateLoad(m state.Source) { + m.Load(0, &x.keep) + m.Load(1, &x.revalidate) + m.Load(2, &x.cacheReaddir) +} + +func (x *overlayMountSourceOperations) StateTypeName() string { + return "pkg/sentry/fs.overlayMountSourceOperations" +} + +func (x *overlayMountSourceOperations) StateFields() []string { + return []string{ + "upper", + "lower", + } } func (x *overlayMountSourceOperations) beforeSave() {} -func (x *overlayMountSourceOperations) save(m state.Map) { + +func (x *overlayMountSourceOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("upper", &x.upper) - m.Save("lower", &x.lower) + m.Save(0, &x.upper) + m.Save(1, &x.lower) } func (x *overlayMountSourceOperations) afterLoad() {} -func (x *overlayMountSourceOperations) load(m state.Map) { - m.Load("upper", &x.upper) - m.Load("lower", &x.lower) + +func (x *overlayMountSourceOperations) StateLoad(m state.Source) { + m.Load(0, &x.upper) + m.Load(1, &x.lower) +} + +func (x *overlayFilesystem) StateTypeName() string { + return "pkg/sentry/fs.overlayFilesystem" +} + +func (x *overlayFilesystem) StateFields() []string { + return []string{} } func (x *overlayFilesystem) beforeSave() {} -func (x *overlayFilesystem) save(m state.Map) { + +func (x *overlayFilesystem) StateSave(m state.Sink) { x.beforeSave() } func (x *overlayFilesystem) afterLoad() {} -func (x *overlayFilesystem) load(m state.Map) { + +func (x *overlayFilesystem) StateLoad(m state.Source) { +} + +func (x *Mount) StateTypeName() string { + return "pkg/sentry/fs.Mount" +} + +func (x *Mount) StateFields() []string { + return []string{ + "ID", + "ParentID", + "root", + "previous", + } } func (x *Mount) beforeSave() {} -func (x *Mount) save(m state.Map) { + +func (x *Mount) StateSave(m state.Sink) { x.beforeSave() - m.Save("ID", &x.ID) - m.Save("ParentID", &x.ParentID) - m.Save("root", &x.root) - m.Save("previous", &x.previous) + m.Save(0, &x.ID) + m.Save(1, &x.ParentID) + m.Save(2, &x.root) + m.Save(3, &x.previous) } func (x *Mount) afterLoad() {} -func (x *Mount) load(m state.Map) { - m.Load("ID", &x.ID) - m.Load("ParentID", &x.ParentID) - m.Load("root", &x.root) - m.Load("previous", &x.previous) + +func (x *Mount) StateLoad(m state.Source) { + m.Load(0, &x.ID) + m.Load(1, &x.ParentID) + m.Load(2, &x.root) + m.Load(3, &x.previous) +} + +func (x *MountNamespace) StateTypeName() string { + return "pkg/sentry/fs.MountNamespace" +} + +func (x *MountNamespace) StateFields() []string { + return []string{ + "AtomicRefCount", + "userns", + "root", + "mounts", + "mountID", + } } func (x *MountNamespace) beforeSave() {} -func (x *MountNamespace) save(m state.Map) { + +func (x *MountNamespace) StateSave(m state.Sink) { x.beforeSave() - m.Save("AtomicRefCount", &x.AtomicRefCount) - m.Save("userns", &x.userns) - m.Save("root", &x.root) - m.Save("mounts", &x.mounts) - m.Save("mountID", &x.mountID) + m.Save(0, &x.AtomicRefCount) + m.Save(1, &x.userns) + m.Save(2, &x.root) + m.Save(3, &x.mounts) + m.Save(4, &x.mountID) } func (x *MountNamespace) afterLoad() {} -func (x *MountNamespace) load(m state.Map) { - m.Load("AtomicRefCount", &x.AtomicRefCount) - m.Load("userns", &x.userns) - m.Load("root", &x.root) - m.Load("mounts", &x.mounts) - m.Load("mountID", &x.mountID) + +func (x *MountNamespace) StateLoad(m state.Source) { + m.Load(0, &x.AtomicRefCount) + m.Load(1, &x.userns) + m.Load(2, &x.root) + m.Load(3, &x.mounts) + m.Load(4, &x.mountID) +} + +func (x *overlayEntry) StateTypeName() string { + return "pkg/sentry/fs.overlayEntry" +} + +func (x *overlayEntry) StateFields() []string { + return []string{ + "lowerExists", + "lower", + "mappings", + "upper", + "dirCache", + } } func (x *overlayEntry) beforeSave() {} -func (x *overlayEntry) save(m state.Map) { + +func (x *overlayEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("lowerExists", &x.lowerExists) - m.Save("lower", &x.lower) - m.Save("mappings", &x.mappings) - m.Save("upper", &x.upper) - m.Save("dirCache", &x.dirCache) + m.Save(0, &x.lowerExists) + m.Save(1, &x.lower) + m.Save(2, &x.mappings) + m.Save(3, &x.upper) + m.Save(4, &x.dirCache) } func (x *overlayEntry) afterLoad() {} -func (x *overlayEntry) load(m state.Map) { - m.Load("lowerExists", &x.lowerExists) - m.Load("lower", &x.lower) - m.Load("mappings", &x.mappings) - m.Load("upper", &x.upper) - m.Load("dirCache", &x.dirCache) + +func (x *overlayEntry) StateLoad(m state.Source) { + m.Load(0, &x.lowerExists) + m.Load(1, &x.lower) + m.Load(2, &x.mappings) + m.Load(3, &x.upper) + m.Load(4, &x.dirCache) } func init() { - state.Register("pkg/sentry/fs.StableAttr", (*StableAttr)(nil), state.Fns{Save: (*StableAttr).save, Load: (*StableAttr).load}) - state.Register("pkg/sentry/fs.UnstableAttr", (*UnstableAttr)(nil), state.Fns{Save: (*UnstableAttr).save, Load: (*UnstableAttr).load}) - state.Register("pkg/sentry/fs.AttrMask", (*AttrMask)(nil), state.Fns{Save: (*AttrMask).save, Load: (*AttrMask).load}) - state.Register("pkg/sentry/fs.PermMask", (*PermMask)(nil), state.Fns{Save: (*PermMask).save, Load: (*PermMask).load}) - state.Register("pkg/sentry/fs.FilePermissions", (*FilePermissions)(nil), state.Fns{Save: (*FilePermissions).save, Load: (*FilePermissions).load}) - state.Register("pkg/sentry/fs.FileOwner", (*FileOwner)(nil), state.Fns{Save: (*FileOwner).save, Load: (*FileOwner).load}) - state.Register("pkg/sentry/fs.DentAttr", (*DentAttr)(nil), state.Fns{Save: (*DentAttr).save, Load: (*DentAttr).load}) - state.Register("pkg/sentry/fs.SortedDentryMap", (*SortedDentryMap)(nil), state.Fns{Save: (*SortedDentryMap).save, Load: (*SortedDentryMap).load}) - state.Register("pkg/sentry/fs.Dirent", (*Dirent)(nil), state.Fns{Save: (*Dirent).save, Load: (*Dirent).load}) - state.Register("pkg/sentry/fs.DirentCache", (*DirentCache)(nil), state.Fns{Save: (*DirentCache).save, Load: (*DirentCache).load}) - state.Register("pkg/sentry/fs.DirentCacheLimiter", (*DirentCacheLimiter)(nil), state.Fns{Save: (*DirentCacheLimiter).save, Load: (*DirentCacheLimiter).load}) - state.Register("pkg/sentry/fs.direntList", (*direntList)(nil), state.Fns{Save: (*direntList).save, Load: (*direntList).load}) - state.Register("pkg/sentry/fs.direntEntry", (*direntEntry)(nil), state.Fns{Save: (*direntEntry).save, Load: (*direntEntry).load}) - state.Register("pkg/sentry/fs.eventList", (*eventList)(nil), state.Fns{Save: (*eventList).save, Load: (*eventList).load}) - state.Register("pkg/sentry/fs.eventEntry", (*eventEntry)(nil), state.Fns{Save: (*eventEntry).save, Load: (*eventEntry).load}) - state.Register("pkg/sentry/fs.File", (*File)(nil), state.Fns{Save: (*File).save, Load: (*File).load}) - state.Register("pkg/sentry/fs.overlayFileOperations", (*overlayFileOperations)(nil), state.Fns{Save: (*overlayFileOperations).save, Load: (*overlayFileOperations).load}) - state.Register("pkg/sentry/fs.overlayMappingIdentity", (*overlayMappingIdentity)(nil), state.Fns{Save: (*overlayMappingIdentity).save, Load: (*overlayMappingIdentity).load}) - state.Register("pkg/sentry/fs.MountSourceFlags", (*MountSourceFlags)(nil), state.Fns{Save: (*MountSourceFlags).save, Load: (*MountSourceFlags).load}) - state.Register("pkg/sentry/fs.FileFlags", (*FileFlags)(nil), state.Fns{Save: (*FileFlags).save, Load: (*FileFlags).load}) - state.Register("pkg/sentry/fs.Inode", (*Inode)(nil), state.Fns{Save: (*Inode).save, Load: (*Inode).load}) - state.Register("pkg/sentry/fs.LockCtx", (*LockCtx)(nil), state.Fns{Save: (*LockCtx).save, Load: (*LockCtx).load}) - state.Register("pkg/sentry/fs.Watches", (*Watches)(nil), state.Fns{Save: (*Watches).save, Load: (*Watches).load}) - state.Register("pkg/sentry/fs.Inotify", (*Inotify)(nil), state.Fns{Save: (*Inotify).save, Load: (*Inotify).load}) - state.Register("pkg/sentry/fs.Event", (*Event)(nil), state.Fns{Save: (*Event).save, Load: (*Event).load}) - state.Register("pkg/sentry/fs.Watch", (*Watch)(nil), state.Fns{Save: (*Watch).save, Load: (*Watch).load}) - state.Register("pkg/sentry/fs.MountSource", (*MountSource)(nil), state.Fns{Save: (*MountSource).save, Load: (*MountSource).load}) - state.Register("pkg/sentry/fs.SimpleMountSourceOperations", (*SimpleMountSourceOperations)(nil), state.Fns{Save: (*SimpleMountSourceOperations).save, Load: (*SimpleMountSourceOperations).load}) - state.Register("pkg/sentry/fs.overlayMountSourceOperations", (*overlayMountSourceOperations)(nil), state.Fns{Save: (*overlayMountSourceOperations).save, Load: (*overlayMountSourceOperations).load}) - state.Register("pkg/sentry/fs.overlayFilesystem", (*overlayFilesystem)(nil), state.Fns{Save: (*overlayFilesystem).save, Load: (*overlayFilesystem).load}) - state.Register("pkg/sentry/fs.Mount", (*Mount)(nil), state.Fns{Save: (*Mount).save, Load: (*Mount).load}) - state.Register("pkg/sentry/fs.MountNamespace", (*MountNamespace)(nil), state.Fns{Save: (*MountNamespace).save, Load: (*MountNamespace).load}) - state.Register("pkg/sentry/fs.overlayEntry", (*overlayEntry)(nil), state.Fns{Save: (*overlayEntry).save, Load: (*overlayEntry).load}) + state.Register((*StableAttr)(nil)) + state.Register((*UnstableAttr)(nil)) + state.Register((*AttrMask)(nil)) + state.Register((*PermMask)(nil)) + state.Register((*FilePermissions)(nil)) + state.Register((*FileOwner)(nil)) + state.Register((*DentAttr)(nil)) + state.Register((*SortedDentryMap)(nil)) + state.Register((*Dirent)(nil)) + state.Register((*DirentCache)(nil)) + state.Register((*DirentCacheLimiter)(nil)) + state.Register((*direntList)(nil)) + state.Register((*direntEntry)(nil)) + state.Register((*eventList)(nil)) + state.Register((*eventEntry)(nil)) + state.Register((*File)(nil)) + state.Register((*overlayFileOperations)(nil)) + state.Register((*overlayMappingIdentity)(nil)) + state.Register((*MountSourceFlags)(nil)) + state.Register((*FileFlags)(nil)) + state.Register((*Inode)(nil)) + state.Register((*LockCtx)(nil)) + state.Register((*Watches)(nil)) + state.Register((*Inotify)(nil)) + state.Register((*Event)(nil)) + state.Register((*Watch)(nil)) + state.Register((*MountSource)(nil)) + state.Register((*SimpleMountSourceOperations)(nil)) + state.Register((*overlayMountSourceOperations)(nil)) + state.Register((*overlayFilesystem)(nil)) + state.Register((*Mount)(nil)) + state.Register((*MountNamespace)(nil)) + state.Register((*overlayEntry)(nil)) } diff --git a/pkg/sentry/fs/fsutil/fsutil_impl_state_autogen.go b/pkg/sentry/fs/fsutil/fsutil_impl_state_autogen.go index 79d4610f0..b3270d11d 100644 --- a/pkg/sentry/fs/fsutil/fsutil_impl_state_autogen.go +++ b/pkg/sentry/fs/fsutil/fsutil_impl_state_autogen.go @@ -6,170 +6,305 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *DirtySet) StateTypeName() string { + return "pkg/sentry/fs/fsutil.DirtySet" +} + +func (x *DirtySet) StateFields() []string { + return []string{ + "root", + } +} + func (x *DirtySet) beforeSave() {} -func (x *DirtySet) save(m state.Map) { + +func (x *DirtySet) StateSave(m state.Sink) { x.beforeSave() var root *DirtySegmentDataSlices = x.saveRoot() - m.SaveValue("root", root) + m.SaveValue(0, root) } func (x *DirtySet) afterLoad() {} -func (x *DirtySet) load(m state.Map) { - m.LoadValue("root", new(*DirtySegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*DirtySegmentDataSlices)) }) + +func (x *DirtySet) StateLoad(m state.Source) { + m.LoadValue(0, new(*DirtySegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*DirtySegmentDataSlices)) }) +} + +func (x *Dirtynode) StateTypeName() string { + return "pkg/sentry/fs/fsutil.Dirtynode" +} + +func (x *Dirtynode) StateFields() []string { + return []string{ + "nrSegments", + "parent", + "parentIndex", + "hasChildren", + "maxGap", + "keys", + "values", + "children", + } } func (x *Dirtynode) beforeSave() {} -func (x *Dirtynode) save(m state.Map) { + +func (x *Dirtynode) StateSave(m state.Sink) { x.beforeSave() - m.Save("nrSegments", &x.nrSegments) - m.Save("parent", &x.parent) - m.Save("parentIndex", &x.parentIndex) - m.Save("hasChildren", &x.hasChildren) - m.Save("maxGap", &x.maxGap) - m.Save("keys", &x.keys) - m.Save("values", &x.values) - m.Save("children", &x.children) + m.Save(0, &x.nrSegments) + m.Save(1, &x.parent) + m.Save(2, &x.parentIndex) + m.Save(3, &x.hasChildren) + m.Save(4, &x.maxGap) + m.Save(5, &x.keys) + m.Save(6, &x.values) + m.Save(7, &x.children) } func (x *Dirtynode) afterLoad() {} -func (x *Dirtynode) load(m state.Map) { - m.Load("nrSegments", &x.nrSegments) - m.Load("parent", &x.parent) - m.Load("parentIndex", &x.parentIndex) - m.Load("hasChildren", &x.hasChildren) - m.Load("maxGap", &x.maxGap) - m.Load("keys", &x.keys) - m.Load("values", &x.values) - m.Load("children", &x.children) + +func (x *Dirtynode) StateLoad(m state.Source) { + m.Load(0, &x.nrSegments) + m.Load(1, &x.parent) + m.Load(2, &x.parentIndex) + m.Load(3, &x.hasChildren) + m.Load(4, &x.maxGap) + m.Load(5, &x.keys) + m.Load(6, &x.values) + m.Load(7, &x.children) +} + +func (x *DirtySegmentDataSlices) StateTypeName() string { + return "pkg/sentry/fs/fsutil.DirtySegmentDataSlices" +} + +func (x *DirtySegmentDataSlices) StateFields() []string { + return []string{ + "Start", + "End", + "Values", + } } func (x *DirtySegmentDataSlices) beforeSave() {} -func (x *DirtySegmentDataSlices) save(m state.Map) { + +func (x *DirtySegmentDataSlices) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) - m.Save("Values", &x.Values) + m.Save(0, &x.Start) + m.Save(1, &x.End) + m.Save(2, &x.Values) } func (x *DirtySegmentDataSlices) afterLoad() {} -func (x *DirtySegmentDataSlices) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) - m.Load("Values", &x.Values) + +func (x *DirtySegmentDataSlices) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) + m.Load(2, &x.Values) +} + +func (x *FileRangeSet) StateTypeName() string { + return "pkg/sentry/fs/fsutil.FileRangeSet" +} + +func (x *FileRangeSet) StateFields() []string { + return []string{ + "root", + } } func (x *FileRangeSet) beforeSave() {} -func (x *FileRangeSet) save(m state.Map) { + +func (x *FileRangeSet) StateSave(m state.Sink) { x.beforeSave() var root *FileRangeSegmentDataSlices = x.saveRoot() - m.SaveValue("root", root) + m.SaveValue(0, root) } func (x *FileRangeSet) afterLoad() {} -func (x *FileRangeSet) load(m state.Map) { - m.LoadValue("root", new(*FileRangeSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*FileRangeSegmentDataSlices)) }) + +func (x *FileRangeSet) StateLoad(m state.Source) { + m.LoadValue(0, new(*FileRangeSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*FileRangeSegmentDataSlices)) }) +} + +func (x *FileRangenode) StateTypeName() string { + return "pkg/sentry/fs/fsutil.FileRangenode" +} + +func (x *FileRangenode) StateFields() []string { + return []string{ + "nrSegments", + "parent", + "parentIndex", + "hasChildren", + "maxGap", + "keys", + "values", + "children", + } } func (x *FileRangenode) beforeSave() {} -func (x *FileRangenode) save(m state.Map) { + +func (x *FileRangenode) StateSave(m state.Sink) { x.beforeSave() - m.Save("nrSegments", &x.nrSegments) - m.Save("parent", &x.parent) - m.Save("parentIndex", &x.parentIndex) - m.Save("hasChildren", &x.hasChildren) - m.Save("maxGap", &x.maxGap) - m.Save("keys", &x.keys) - m.Save("values", &x.values) - m.Save("children", &x.children) + m.Save(0, &x.nrSegments) + m.Save(1, &x.parent) + m.Save(2, &x.parentIndex) + m.Save(3, &x.hasChildren) + m.Save(4, &x.maxGap) + m.Save(5, &x.keys) + m.Save(6, &x.values) + m.Save(7, &x.children) } func (x *FileRangenode) afterLoad() {} -func (x *FileRangenode) load(m state.Map) { - m.Load("nrSegments", &x.nrSegments) - m.Load("parent", &x.parent) - m.Load("parentIndex", &x.parentIndex) - m.Load("hasChildren", &x.hasChildren) - m.Load("maxGap", &x.maxGap) - m.Load("keys", &x.keys) - m.Load("values", &x.values) - m.Load("children", &x.children) + +func (x *FileRangenode) StateLoad(m state.Source) { + m.Load(0, &x.nrSegments) + m.Load(1, &x.parent) + m.Load(2, &x.parentIndex) + m.Load(3, &x.hasChildren) + m.Load(4, &x.maxGap) + m.Load(5, &x.keys) + m.Load(6, &x.values) + m.Load(7, &x.children) +} + +func (x *FileRangeSegmentDataSlices) StateTypeName() string { + return "pkg/sentry/fs/fsutil.FileRangeSegmentDataSlices" +} + +func (x *FileRangeSegmentDataSlices) StateFields() []string { + return []string{ + "Start", + "End", + "Values", + } } func (x *FileRangeSegmentDataSlices) beforeSave() {} -func (x *FileRangeSegmentDataSlices) save(m state.Map) { + +func (x *FileRangeSegmentDataSlices) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) - m.Save("Values", &x.Values) + m.Save(0, &x.Start) + m.Save(1, &x.End) + m.Save(2, &x.Values) } func (x *FileRangeSegmentDataSlices) afterLoad() {} -func (x *FileRangeSegmentDataSlices) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) - m.Load("Values", &x.Values) + +func (x *FileRangeSegmentDataSlices) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) + m.Load(2, &x.Values) +} + +func (x *FrameRefSet) StateTypeName() string { + return "pkg/sentry/fs/fsutil.FrameRefSet" +} + +func (x *FrameRefSet) StateFields() []string { + return []string{ + "root", + } } func (x *FrameRefSet) beforeSave() {} -func (x *FrameRefSet) save(m state.Map) { + +func (x *FrameRefSet) StateSave(m state.Sink) { x.beforeSave() var root *FrameRefSegmentDataSlices = x.saveRoot() - m.SaveValue("root", root) + m.SaveValue(0, root) } func (x *FrameRefSet) afterLoad() {} -func (x *FrameRefSet) load(m state.Map) { - m.LoadValue("root", new(*FrameRefSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*FrameRefSegmentDataSlices)) }) + +func (x *FrameRefSet) StateLoad(m state.Source) { + m.LoadValue(0, new(*FrameRefSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*FrameRefSegmentDataSlices)) }) +} + +func (x *FrameRefnode) StateTypeName() string { + return "pkg/sentry/fs/fsutil.FrameRefnode" +} + +func (x *FrameRefnode) StateFields() []string { + return []string{ + "nrSegments", + "parent", + "parentIndex", + "hasChildren", + "maxGap", + "keys", + "values", + "children", + } } func (x *FrameRefnode) beforeSave() {} -func (x *FrameRefnode) save(m state.Map) { + +func (x *FrameRefnode) StateSave(m state.Sink) { x.beforeSave() - m.Save("nrSegments", &x.nrSegments) - m.Save("parent", &x.parent) - m.Save("parentIndex", &x.parentIndex) - m.Save("hasChildren", &x.hasChildren) - m.Save("maxGap", &x.maxGap) - m.Save("keys", &x.keys) - m.Save("values", &x.values) - m.Save("children", &x.children) + m.Save(0, &x.nrSegments) + m.Save(1, &x.parent) + m.Save(2, &x.parentIndex) + m.Save(3, &x.hasChildren) + m.Save(4, &x.maxGap) + m.Save(5, &x.keys) + m.Save(6, &x.values) + m.Save(7, &x.children) } func (x *FrameRefnode) afterLoad() {} -func (x *FrameRefnode) load(m state.Map) { - m.Load("nrSegments", &x.nrSegments) - m.Load("parent", &x.parent) - m.Load("parentIndex", &x.parentIndex) - m.Load("hasChildren", &x.hasChildren) - m.Load("maxGap", &x.maxGap) - m.Load("keys", &x.keys) - m.Load("values", &x.values) - m.Load("children", &x.children) + +func (x *FrameRefnode) StateLoad(m state.Source) { + m.Load(0, &x.nrSegments) + m.Load(1, &x.parent) + m.Load(2, &x.parentIndex) + m.Load(3, &x.hasChildren) + m.Load(4, &x.maxGap) + m.Load(5, &x.keys) + m.Load(6, &x.values) + m.Load(7, &x.children) +} + +func (x *FrameRefSegmentDataSlices) StateTypeName() string { + return "pkg/sentry/fs/fsutil.FrameRefSegmentDataSlices" +} + +func (x *FrameRefSegmentDataSlices) StateFields() []string { + return []string{ + "Start", + "End", + "Values", + } } func (x *FrameRefSegmentDataSlices) beforeSave() {} -func (x *FrameRefSegmentDataSlices) save(m state.Map) { + +func (x *FrameRefSegmentDataSlices) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) - m.Save("Values", &x.Values) + m.Save(0, &x.Start) + m.Save(1, &x.End) + m.Save(2, &x.Values) } func (x *FrameRefSegmentDataSlices) afterLoad() {} -func (x *FrameRefSegmentDataSlices) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) - m.Load("Values", &x.Values) + +func (x *FrameRefSegmentDataSlices) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) + m.Load(2, &x.Values) } func init() { - state.Register("pkg/sentry/fs/fsutil.DirtySet", (*DirtySet)(nil), state.Fns{Save: (*DirtySet).save, Load: (*DirtySet).load}) - state.Register("pkg/sentry/fs/fsutil.Dirtynode", (*Dirtynode)(nil), state.Fns{Save: (*Dirtynode).save, Load: (*Dirtynode).load}) - state.Register("pkg/sentry/fs/fsutil.DirtySegmentDataSlices", (*DirtySegmentDataSlices)(nil), state.Fns{Save: (*DirtySegmentDataSlices).save, Load: (*DirtySegmentDataSlices).load}) - state.Register("pkg/sentry/fs/fsutil.FileRangeSet", (*FileRangeSet)(nil), state.Fns{Save: (*FileRangeSet).save, Load: (*FileRangeSet).load}) - state.Register("pkg/sentry/fs/fsutil.FileRangenode", (*FileRangenode)(nil), state.Fns{Save: (*FileRangenode).save, Load: (*FileRangenode).load}) - state.Register("pkg/sentry/fs/fsutil.FileRangeSegmentDataSlices", (*FileRangeSegmentDataSlices)(nil), state.Fns{Save: (*FileRangeSegmentDataSlices).save, Load: (*FileRangeSegmentDataSlices).load}) - state.Register("pkg/sentry/fs/fsutil.FrameRefSet", (*FrameRefSet)(nil), state.Fns{Save: (*FrameRefSet).save, Load: (*FrameRefSet).load}) - state.Register("pkg/sentry/fs/fsutil.FrameRefnode", (*FrameRefnode)(nil), state.Fns{Save: (*FrameRefnode).save, Load: (*FrameRefnode).load}) - state.Register("pkg/sentry/fs/fsutil.FrameRefSegmentDataSlices", (*FrameRefSegmentDataSlices)(nil), state.Fns{Save: (*FrameRefSegmentDataSlices).save, Load: (*FrameRefSegmentDataSlices).load}) + state.Register((*DirtySet)(nil)) + state.Register((*Dirtynode)(nil)) + state.Register((*DirtySegmentDataSlices)(nil)) + state.Register((*FileRangeSet)(nil)) + state.Register((*FileRangenode)(nil)) + state.Register((*FileRangeSegmentDataSlices)(nil)) + state.Register((*FrameRefSet)(nil)) + state.Register((*FrameRefnode)(nil)) + state.Register((*FrameRefSegmentDataSlices)(nil)) } diff --git a/pkg/sentry/fs/fsutil/fsutil_state_autogen.go b/pkg/sentry/fs/fsutil/fsutil_state_autogen.go index 80b93ad25..8e2a4c961 100644 --- a/pkg/sentry/fs/fsutil/fsutil_state_autogen.go +++ b/pkg/sentry/fs/fsutil/fsutil_state_autogen.go @@ -6,199 +6,378 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *DirtyInfo) StateTypeName() string { + return "pkg/sentry/fs/fsutil.DirtyInfo" +} + +func (x *DirtyInfo) StateFields() []string { + return []string{ + "Keep", + } +} + func (x *DirtyInfo) beforeSave() {} -func (x *DirtyInfo) save(m state.Map) { + +func (x *DirtyInfo) StateSave(m state.Sink) { x.beforeSave() - m.Save("Keep", &x.Keep) + m.Save(0, &x.Keep) } func (x *DirtyInfo) afterLoad() {} -func (x *DirtyInfo) load(m state.Map) { - m.Load("Keep", &x.Keep) + +func (x *DirtyInfo) StateLoad(m state.Source) { + m.Load(0, &x.Keep) +} + +func (x *StaticDirFileOperations) StateTypeName() string { + return "pkg/sentry/fs/fsutil.StaticDirFileOperations" +} + +func (x *StaticDirFileOperations) StateFields() []string { + return []string{ + "dentryMap", + "dirCursor", + } } func (x *StaticDirFileOperations) beforeSave() {} -func (x *StaticDirFileOperations) save(m state.Map) { + +func (x *StaticDirFileOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("dentryMap", &x.dentryMap) - m.Save("dirCursor", &x.dirCursor) + m.Save(0, &x.dentryMap) + m.Save(1, &x.dirCursor) } func (x *StaticDirFileOperations) afterLoad() {} -func (x *StaticDirFileOperations) load(m state.Map) { - m.Load("dentryMap", &x.dentryMap) - m.Load("dirCursor", &x.dirCursor) + +func (x *StaticDirFileOperations) StateLoad(m state.Source) { + m.Load(0, &x.dentryMap) + m.Load(1, &x.dirCursor) +} + +func (x *NoReadWriteFile) StateTypeName() string { + return "pkg/sentry/fs/fsutil.NoReadWriteFile" +} + +func (x *NoReadWriteFile) StateFields() []string { + return []string{} } func (x *NoReadWriteFile) beforeSave() {} -func (x *NoReadWriteFile) save(m state.Map) { + +func (x *NoReadWriteFile) StateSave(m state.Sink) { x.beforeSave() } func (x *NoReadWriteFile) afterLoad() {} -func (x *NoReadWriteFile) load(m state.Map) { + +func (x *NoReadWriteFile) StateLoad(m state.Source) { +} + +func (x *FileStaticContentReader) StateTypeName() string { + return "pkg/sentry/fs/fsutil.FileStaticContentReader" +} + +func (x *FileStaticContentReader) StateFields() []string { + return []string{ + "content", + } } func (x *FileStaticContentReader) beforeSave() {} -func (x *FileStaticContentReader) save(m state.Map) { + +func (x *FileStaticContentReader) StateSave(m state.Sink) { x.beforeSave() - m.Save("content", &x.content) + m.Save(0, &x.content) } func (x *FileStaticContentReader) afterLoad() {} -func (x *FileStaticContentReader) load(m state.Map) { - m.Load("content", &x.content) + +func (x *FileStaticContentReader) StateLoad(m state.Source) { + m.Load(0, &x.content) +} + +func (x *HostFileMapper) StateTypeName() string { + return "pkg/sentry/fs/fsutil.HostFileMapper" +} + +func (x *HostFileMapper) StateFields() []string { + return []string{ + "refs", + } } func (x *HostFileMapper) beforeSave() {} -func (x *HostFileMapper) save(m state.Map) { + +func (x *HostFileMapper) StateSave(m state.Sink) { x.beforeSave() - m.Save("refs", &x.refs) + m.Save(0, &x.refs) } -func (x *HostFileMapper) load(m state.Map) { - m.Load("refs", &x.refs) +func (x *HostFileMapper) StateLoad(m state.Source) { + m.Load(0, &x.refs) m.AfterLoad(x.afterLoad) } +func (x *HostMappable) StateTypeName() string { + return "pkg/sentry/fs/fsutil.HostMappable" +} + +func (x *HostMappable) StateFields() []string { + return []string{ + "hostFileMapper", + "backingFile", + "mappings", + } +} + func (x *HostMappable) beforeSave() {} -func (x *HostMappable) save(m state.Map) { + +func (x *HostMappable) StateSave(m state.Sink) { x.beforeSave() - m.Save("hostFileMapper", &x.hostFileMapper) - m.Save("backingFile", &x.backingFile) - m.Save("mappings", &x.mappings) + m.Save(0, &x.hostFileMapper) + m.Save(1, &x.backingFile) + m.Save(2, &x.mappings) } func (x *HostMappable) afterLoad() {} -func (x *HostMappable) load(m state.Map) { - m.Load("hostFileMapper", &x.hostFileMapper) - m.Load("backingFile", &x.backingFile) - m.Load("mappings", &x.mappings) + +func (x *HostMappable) StateLoad(m state.Source) { + m.Load(0, &x.hostFileMapper) + m.Load(1, &x.backingFile) + m.Load(2, &x.mappings) +} + +func (x *SimpleFileInode) StateTypeName() string { + return "pkg/sentry/fs/fsutil.SimpleFileInode" +} + +func (x *SimpleFileInode) StateFields() []string { + return []string{ + "InodeSimpleAttributes", + } } func (x *SimpleFileInode) beforeSave() {} -func (x *SimpleFileInode) save(m state.Map) { + +func (x *SimpleFileInode) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeSimpleAttributes", &x.InodeSimpleAttributes) + m.Save(0, &x.InodeSimpleAttributes) } func (x *SimpleFileInode) afterLoad() {} -func (x *SimpleFileInode) load(m state.Map) { - m.Load("InodeSimpleAttributes", &x.InodeSimpleAttributes) + +func (x *SimpleFileInode) StateLoad(m state.Source) { + m.Load(0, &x.InodeSimpleAttributes) +} + +func (x *NoReadWriteFileInode) StateTypeName() string { + return "pkg/sentry/fs/fsutil.NoReadWriteFileInode" +} + +func (x *NoReadWriteFileInode) StateFields() []string { + return []string{ + "InodeSimpleAttributes", + } } func (x *NoReadWriteFileInode) beforeSave() {} -func (x *NoReadWriteFileInode) save(m state.Map) { + +func (x *NoReadWriteFileInode) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeSimpleAttributes", &x.InodeSimpleAttributes) + m.Save(0, &x.InodeSimpleAttributes) } func (x *NoReadWriteFileInode) afterLoad() {} -func (x *NoReadWriteFileInode) load(m state.Map) { - m.Load("InodeSimpleAttributes", &x.InodeSimpleAttributes) + +func (x *NoReadWriteFileInode) StateLoad(m state.Source) { + m.Load(0, &x.InodeSimpleAttributes) +} + +func (x *InodeSimpleAttributes) StateTypeName() string { + return "pkg/sentry/fs/fsutil.InodeSimpleAttributes" +} + +func (x *InodeSimpleAttributes) StateFields() []string { + return []string{ + "fsType", + "unstable", + } } func (x *InodeSimpleAttributes) beforeSave() {} -func (x *InodeSimpleAttributes) save(m state.Map) { + +func (x *InodeSimpleAttributes) StateSave(m state.Sink) { x.beforeSave() - m.Save("fsType", &x.fsType) - m.Save("unstable", &x.unstable) + m.Save(0, &x.fsType) + m.Save(1, &x.unstable) } func (x *InodeSimpleAttributes) afterLoad() {} -func (x *InodeSimpleAttributes) load(m state.Map) { - m.Load("fsType", &x.fsType) - m.Load("unstable", &x.unstable) + +func (x *InodeSimpleAttributes) StateLoad(m state.Source) { + m.Load(0, &x.fsType) + m.Load(1, &x.unstable) +} + +func (x *InodeSimpleExtendedAttributes) StateTypeName() string { + return "pkg/sentry/fs/fsutil.InodeSimpleExtendedAttributes" +} + +func (x *InodeSimpleExtendedAttributes) StateFields() []string { + return []string{ + "xattrs", + } } func (x *InodeSimpleExtendedAttributes) beforeSave() {} -func (x *InodeSimpleExtendedAttributes) save(m state.Map) { + +func (x *InodeSimpleExtendedAttributes) StateSave(m state.Sink) { x.beforeSave() - m.Save("xattrs", &x.xattrs) + m.Save(0, &x.xattrs) } func (x *InodeSimpleExtendedAttributes) afterLoad() {} -func (x *InodeSimpleExtendedAttributes) load(m state.Map) { - m.Load("xattrs", &x.xattrs) + +func (x *InodeSimpleExtendedAttributes) StateLoad(m state.Source) { + m.Load(0, &x.xattrs) +} + +func (x *staticFile) StateTypeName() string { + return "pkg/sentry/fs/fsutil.staticFile" +} + +func (x *staticFile) StateFields() []string { + return []string{ + "FileStaticContentReader", + } } func (x *staticFile) beforeSave() {} -func (x *staticFile) save(m state.Map) { + +func (x *staticFile) StateSave(m state.Sink) { x.beforeSave() - m.Save("FileStaticContentReader", &x.FileStaticContentReader) + m.Save(0, &x.FileStaticContentReader) } func (x *staticFile) afterLoad() {} -func (x *staticFile) load(m state.Map) { - m.Load("FileStaticContentReader", &x.FileStaticContentReader) + +func (x *staticFile) StateLoad(m state.Source) { + m.Load(0, &x.FileStaticContentReader) +} + +func (x *InodeStaticFileGetter) StateTypeName() string { + return "pkg/sentry/fs/fsutil.InodeStaticFileGetter" +} + +func (x *InodeStaticFileGetter) StateFields() []string { + return []string{ + "Contents", + } } func (x *InodeStaticFileGetter) beforeSave() {} -func (x *InodeStaticFileGetter) save(m state.Map) { + +func (x *InodeStaticFileGetter) StateSave(m state.Sink) { x.beforeSave() - m.Save("Contents", &x.Contents) + m.Save(0, &x.Contents) } func (x *InodeStaticFileGetter) afterLoad() {} -func (x *InodeStaticFileGetter) load(m state.Map) { - m.Load("Contents", &x.Contents) + +func (x *InodeStaticFileGetter) StateLoad(m state.Source) { + m.Load(0, &x.Contents) +} + +func (x *CachingInodeOperations) StateTypeName() string { + return "pkg/sentry/fs/fsutil.CachingInodeOperations" +} + +func (x *CachingInodeOperations) StateFields() []string { + return []string{ + "backingFile", + "mfp", + "opts", + "attr", + "dirtyAttr", + "mappings", + "cache", + "dirty", + "hostFileMapper", + "refs", + } } func (x *CachingInodeOperations) beforeSave() {} -func (x *CachingInodeOperations) save(m state.Map) { + +func (x *CachingInodeOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("backingFile", &x.backingFile) - m.Save("mfp", &x.mfp) - m.Save("opts", &x.opts) - m.Save("attr", &x.attr) - m.Save("dirtyAttr", &x.dirtyAttr) - m.Save("mappings", &x.mappings) - m.Save("cache", &x.cache) - m.Save("dirty", &x.dirty) - m.Save("hostFileMapper", &x.hostFileMapper) - m.Save("refs", &x.refs) + m.Save(0, &x.backingFile) + m.Save(1, &x.mfp) + m.Save(2, &x.opts) + m.Save(3, &x.attr) + m.Save(4, &x.dirtyAttr) + m.Save(5, &x.mappings) + m.Save(6, &x.cache) + m.Save(7, &x.dirty) + m.Save(8, &x.hostFileMapper) + m.Save(9, &x.refs) } func (x *CachingInodeOperations) afterLoad() {} -func (x *CachingInodeOperations) load(m state.Map) { - m.Load("backingFile", &x.backingFile) - m.Load("mfp", &x.mfp) - m.Load("opts", &x.opts) - m.Load("attr", &x.attr) - m.Load("dirtyAttr", &x.dirtyAttr) - m.Load("mappings", &x.mappings) - m.Load("cache", &x.cache) - m.Load("dirty", &x.dirty) - m.Load("hostFileMapper", &x.hostFileMapper) - m.Load("refs", &x.refs) + +func (x *CachingInodeOperations) StateLoad(m state.Source) { + m.Load(0, &x.backingFile) + m.Load(1, &x.mfp) + m.Load(2, &x.opts) + m.Load(3, &x.attr) + m.Load(4, &x.dirtyAttr) + m.Load(5, &x.mappings) + m.Load(6, &x.cache) + m.Load(7, &x.dirty) + m.Load(8, &x.hostFileMapper) + m.Load(9, &x.refs) +} + +func (x *CachingInodeOperationsOptions) StateTypeName() string { + return "pkg/sentry/fs/fsutil.CachingInodeOperationsOptions" +} + +func (x *CachingInodeOperationsOptions) StateFields() []string { + return []string{ + "ForcePageCache", + "LimitHostFDTranslation", + } } func (x *CachingInodeOperationsOptions) beforeSave() {} -func (x *CachingInodeOperationsOptions) save(m state.Map) { + +func (x *CachingInodeOperationsOptions) StateSave(m state.Sink) { x.beforeSave() - m.Save("ForcePageCache", &x.ForcePageCache) - m.Save("LimitHostFDTranslation", &x.LimitHostFDTranslation) + m.Save(0, &x.ForcePageCache) + m.Save(1, &x.LimitHostFDTranslation) } func (x *CachingInodeOperationsOptions) afterLoad() {} -func (x *CachingInodeOperationsOptions) load(m state.Map) { - m.Load("ForcePageCache", &x.ForcePageCache) - m.Load("LimitHostFDTranslation", &x.LimitHostFDTranslation) + +func (x *CachingInodeOperationsOptions) StateLoad(m state.Source) { + m.Load(0, &x.ForcePageCache) + m.Load(1, &x.LimitHostFDTranslation) } func init() { - state.Register("pkg/sentry/fs/fsutil.DirtyInfo", (*DirtyInfo)(nil), state.Fns{Save: (*DirtyInfo).save, Load: (*DirtyInfo).load}) - state.Register("pkg/sentry/fs/fsutil.StaticDirFileOperations", (*StaticDirFileOperations)(nil), state.Fns{Save: (*StaticDirFileOperations).save, Load: (*StaticDirFileOperations).load}) - state.Register("pkg/sentry/fs/fsutil.NoReadWriteFile", (*NoReadWriteFile)(nil), state.Fns{Save: (*NoReadWriteFile).save, Load: (*NoReadWriteFile).load}) - state.Register("pkg/sentry/fs/fsutil.FileStaticContentReader", (*FileStaticContentReader)(nil), state.Fns{Save: (*FileStaticContentReader).save, Load: (*FileStaticContentReader).load}) - state.Register("pkg/sentry/fs/fsutil.HostFileMapper", (*HostFileMapper)(nil), state.Fns{Save: (*HostFileMapper).save, Load: (*HostFileMapper).load}) - state.Register("pkg/sentry/fs/fsutil.HostMappable", (*HostMappable)(nil), state.Fns{Save: (*HostMappable).save, Load: (*HostMappable).load}) - state.Register("pkg/sentry/fs/fsutil.SimpleFileInode", (*SimpleFileInode)(nil), state.Fns{Save: (*SimpleFileInode).save, Load: (*SimpleFileInode).load}) - state.Register("pkg/sentry/fs/fsutil.NoReadWriteFileInode", (*NoReadWriteFileInode)(nil), state.Fns{Save: (*NoReadWriteFileInode).save, Load: (*NoReadWriteFileInode).load}) - state.Register("pkg/sentry/fs/fsutil.InodeSimpleAttributes", (*InodeSimpleAttributes)(nil), state.Fns{Save: (*InodeSimpleAttributes).save, Load: (*InodeSimpleAttributes).load}) - state.Register("pkg/sentry/fs/fsutil.InodeSimpleExtendedAttributes", (*InodeSimpleExtendedAttributes)(nil), state.Fns{Save: (*InodeSimpleExtendedAttributes).save, Load: (*InodeSimpleExtendedAttributes).load}) - state.Register("pkg/sentry/fs/fsutil.staticFile", (*staticFile)(nil), state.Fns{Save: (*staticFile).save, Load: (*staticFile).load}) - state.Register("pkg/sentry/fs/fsutil.InodeStaticFileGetter", (*InodeStaticFileGetter)(nil), state.Fns{Save: (*InodeStaticFileGetter).save, Load: (*InodeStaticFileGetter).load}) - state.Register("pkg/sentry/fs/fsutil.CachingInodeOperations", (*CachingInodeOperations)(nil), state.Fns{Save: (*CachingInodeOperations).save, Load: (*CachingInodeOperations).load}) - state.Register("pkg/sentry/fs/fsutil.CachingInodeOperationsOptions", (*CachingInodeOperationsOptions)(nil), state.Fns{Save: (*CachingInodeOperationsOptions).save, Load: (*CachingInodeOperationsOptions).load}) + state.Register((*DirtyInfo)(nil)) + state.Register((*StaticDirFileOperations)(nil)) + state.Register((*NoReadWriteFile)(nil)) + state.Register((*FileStaticContentReader)(nil)) + state.Register((*HostFileMapper)(nil)) + state.Register((*HostMappable)(nil)) + state.Register((*SimpleFileInode)(nil)) + state.Register((*NoReadWriteFileInode)(nil)) + state.Register((*InodeSimpleAttributes)(nil)) + state.Register((*InodeSimpleExtendedAttributes)(nil)) + state.Register((*staticFile)(nil)) + state.Register((*InodeStaticFileGetter)(nil)) + state.Register((*CachingInodeOperations)(nil)) + state.Register((*CachingInodeOperationsOptions)(nil)) } diff --git a/pkg/sentry/fs/gofer/gofer_state_autogen.go b/pkg/sentry/fs/gofer/gofer_state_autogen.go index 7db9211b4..1f7360ec8 100644 --- a/pkg/sentry/fs/gofer/gofer_state_autogen.go +++ b/pkg/sentry/fs/gofer/gofer_state_autogen.go @@ -6,140 +6,250 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *fifo) StateTypeName() string { + return "pkg/sentry/fs/gofer.fifo" +} + +func (x *fifo) StateFields() []string { + return []string{ + "InodeOperations", + "fileIops", + } +} + func (x *fifo) beforeSave() {} -func (x *fifo) save(m state.Map) { + +func (x *fifo) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeOperations", &x.InodeOperations) - m.Save("fileIops", &x.fileIops) + m.Save(0, &x.InodeOperations) + m.Save(1, &x.fileIops) } func (x *fifo) afterLoad() {} -func (x *fifo) load(m state.Map) { - m.Load("InodeOperations", &x.InodeOperations) - m.Load("fileIops", &x.fileIops) + +func (x *fifo) StateLoad(m state.Source) { + m.Load(0, &x.InodeOperations) + m.Load(1, &x.fileIops) +} + +func (x *fileOperations) StateTypeName() string { + return "pkg/sentry/fs/gofer.fileOperations" +} + +func (x *fileOperations) StateFields() []string { + return []string{ + "inodeOperations", + "dirCursor", + "flags", + } } func (x *fileOperations) beforeSave() {} -func (x *fileOperations) save(m state.Map) { + +func (x *fileOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("inodeOperations", &x.inodeOperations) - m.Save("dirCursor", &x.dirCursor) - m.Save("flags", &x.flags) + m.Save(0, &x.inodeOperations) + m.Save(1, &x.dirCursor) + m.Save(2, &x.flags) } -func (x *fileOperations) load(m state.Map) { - m.LoadWait("inodeOperations", &x.inodeOperations) - m.Load("dirCursor", &x.dirCursor) - m.LoadWait("flags", &x.flags) +func (x *fileOperations) StateLoad(m state.Source) { + m.LoadWait(0, &x.inodeOperations) + m.Load(1, &x.dirCursor) + m.LoadWait(2, &x.flags) m.AfterLoad(x.afterLoad) } +func (x *filesystem) StateTypeName() string { + return "pkg/sentry/fs/gofer.filesystem" +} + +func (x *filesystem) StateFields() []string { + return []string{} +} + func (x *filesystem) beforeSave() {} -func (x *filesystem) save(m state.Map) { + +func (x *filesystem) StateSave(m state.Sink) { x.beforeSave() } func (x *filesystem) afterLoad() {} -func (x *filesystem) load(m state.Map) { + +func (x *filesystem) StateLoad(m state.Source) { +} + +func (x *inodeOperations) StateTypeName() string { + return "pkg/sentry/fs/gofer.inodeOperations" +} + +func (x *inodeOperations) StateFields() []string { + return []string{ + "fileState", + "cachingInodeOps", + } } func (x *inodeOperations) beforeSave() {} -func (x *inodeOperations) save(m state.Map) { + +func (x *inodeOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("fileState", &x.fileState) - m.Save("cachingInodeOps", &x.cachingInodeOps) + m.Save(0, &x.fileState) + m.Save(1, &x.cachingInodeOps) } func (x *inodeOperations) afterLoad() {} -func (x *inodeOperations) load(m state.Map) { - m.LoadWait("fileState", &x.fileState) - m.Load("cachingInodeOps", &x.cachingInodeOps) + +func (x *inodeOperations) StateLoad(m state.Source) { + m.LoadWait(0, &x.fileState) + m.Load(1, &x.cachingInodeOps) +} + +func (x *inodeFileState) StateTypeName() string { + return "pkg/sentry/fs/gofer.inodeFileState" } -func (x *inodeFileState) save(m state.Map) { +func (x *inodeFileState) StateFields() []string { + return []string{ + "s", + "sattr", + "loading", + "savedUAttr", + "hostMappable", + } +} + +func (x *inodeFileState) StateSave(m state.Sink) { x.beforeSave() var loading struct{} = x.saveLoading() - m.SaveValue("loading", loading) - m.Save("s", &x.s) - m.Save("sattr", &x.sattr) - m.Save("savedUAttr", &x.savedUAttr) - m.Save("hostMappable", &x.hostMappable) -} - -func (x *inodeFileState) load(m state.Map) { - m.LoadWait("s", &x.s) - m.LoadWait("sattr", &x.sattr) - m.Load("savedUAttr", &x.savedUAttr) - m.Load("hostMappable", &x.hostMappable) - m.LoadValue("loading", new(struct{}), func(y interface{}) { x.loadLoading(y.(struct{})) }) + m.SaveValue(2, loading) + m.Save(0, &x.s) + m.Save(1, &x.sattr) + m.Save(3, &x.savedUAttr) + m.Save(4, &x.hostMappable) +} + +func (x *inodeFileState) StateLoad(m state.Source) { + m.LoadWait(0, &x.s) + m.LoadWait(1, &x.sattr) + m.Load(3, &x.savedUAttr) + m.Load(4, &x.hostMappable) + m.LoadValue(2, new(struct{}), func(y interface{}) { x.loadLoading(y.(struct{})) }) m.AfterLoad(x.afterLoad) } +func (x *overrideInfo) StateTypeName() string { + return "pkg/sentry/fs/gofer.overrideInfo" +} + +func (x *overrideInfo) StateFields() []string { + return []string{ + "dirent", + "endpoint", + "inode", + } +} + func (x *overrideInfo) beforeSave() {} -func (x *overrideInfo) save(m state.Map) { + +func (x *overrideInfo) StateSave(m state.Sink) { x.beforeSave() - m.Save("dirent", &x.dirent) - m.Save("endpoint", &x.endpoint) - m.Save("inode", &x.inode) + m.Save(0, &x.dirent) + m.Save(1, &x.endpoint) + m.Save(2, &x.inode) } func (x *overrideInfo) afterLoad() {} -func (x *overrideInfo) load(m state.Map) { - m.Load("dirent", &x.dirent) - m.Load("endpoint", &x.endpoint) - m.Load("inode", &x.inode) + +func (x *overrideInfo) StateLoad(m state.Source) { + m.Load(0, &x.dirent) + m.Load(1, &x.endpoint) + m.Load(2, &x.inode) +} + +func (x *overrideMaps) StateTypeName() string { + return "pkg/sentry/fs/gofer.overrideMaps" +} + +func (x *overrideMaps) StateFields() []string { + return []string{ + "pathMap", + } } func (x *overrideMaps) beforeSave() {} -func (x *overrideMaps) save(m state.Map) { + +func (x *overrideMaps) StateSave(m state.Sink) { x.beforeSave() - m.Save("pathMap", &x.pathMap) + m.Save(0, &x.pathMap) } func (x *overrideMaps) afterLoad() {} -func (x *overrideMaps) load(m state.Map) { - m.Load("pathMap", &x.pathMap) + +func (x *overrideMaps) StateLoad(m state.Source) { + m.Load(0, &x.pathMap) +} + +func (x *session) StateTypeName() string { + return "pkg/sentry/fs/gofer.session" +} + +func (x *session) StateFields() []string { + return []string{ + "AtomicRefCount", + "msize", + "version", + "cachePolicy", + "aname", + "superBlockFlags", + "limitHostFDTranslation", + "overlayfsStaleRead", + "connID", + "inodeMappings", + "mounter", + "overrides", + } } -func (x *session) save(m state.Map) { +func (x *session) StateSave(m state.Sink) { x.beforeSave() - m.Save("AtomicRefCount", &x.AtomicRefCount) - m.Save("msize", &x.msize) - m.Save("version", &x.version) - m.Save("cachePolicy", &x.cachePolicy) - m.Save("aname", &x.aname) - m.Save("superBlockFlags", &x.superBlockFlags) - m.Save("limitHostFDTranslation", &x.limitHostFDTranslation) - m.Save("overlayfsStaleRead", &x.overlayfsStaleRead) - m.Save("connID", &x.connID) - m.Save("inodeMappings", &x.inodeMappings) - m.Save("mounter", &x.mounter) - m.Save("overrides", &x.overrides) -} - -func (x *session) load(m state.Map) { - m.Load("AtomicRefCount", &x.AtomicRefCount) - m.LoadWait("msize", &x.msize) - m.LoadWait("version", &x.version) - m.LoadWait("cachePolicy", &x.cachePolicy) - m.LoadWait("aname", &x.aname) - m.LoadWait("superBlockFlags", &x.superBlockFlags) - m.Load("limitHostFDTranslation", &x.limitHostFDTranslation) - m.Load("overlayfsStaleRead", &x.overlayfsStaleRead) - m.LoadWait("connID", &x.connID) - m.LoadWait("inodeMappings", &x.inodeMappings) - m.LoadWait("mounter", &x.mounter) - m.LoadWait("overrides", &x.overrides) + m.Save(0, &x.AtomicRefCount) + m.Save(1, &x.msize) + m.Save(2, &x.version) + m.Save(3, &x.cachePolicy) + m.Save(4, &x.aname) + m.Save(5, &x.superBlockFlags) + m.Save(6, &x.limitHostFDTranslation) + m.Save(7, &x.overlayfsStaleRead) + m.Save(8, &x.connID) + m.Save(9, &x.inodeMappings) + m.Save(10, &x.mounter) + m.Save(11, &x.overrides) +} + +func (x *session) StateLoad(m state.Source) { + m.Load(0, &x.AtomicRefCount) + m.LoadWait(1, &x.msize) + m.LoadWait(2, &x.version) + m.LoadWait(3, &x.cachePolicy) + m.LoadWait(4, &x.aname) + m.LoadWait(5, &x.superBlockFlags) + m.Load(6, &x.limitHostFDTranslation) + m.Load(7, &x.overlayfsStaleRead) + m.LoadWait(8, &x.connID) + m.LoadWait(9, &x.inodeMappings) + m.LoadWait(10, &x.mounter) + m.LoadWait(11, &x.overrides) m.AfterLoad(x.afterLoad) } func init() { - state.Register("pkg/sentry/fs/gofer.fifo", (*fifo)(nil), state.Fns{Save: (*fifo).save, Load: (*fifo).load}) - state.Register("pkg/sentry/fs/gofer.fileOperations", (*fileOperations)(nil), state.Fns{Save: (*fileOperations).save, Load: (*fileOperations).load}) - state.Register("pkg/sentry/fs/gofer.filesystem", (*filesystem)(nil), state.Fns{Save: (*filesystem).save, Load: (*filesystem).load}) - state.Register("pkg/sentry/fs/gofer.inodeOperations", (*inodeOperations)(nil), state.Fns{Save: (*inodeOperations).save, Load: (*inodeOperations).load}) - state.Register("pkg/sentry/fs/gofer.inodeFileState", (*inodeFileState)(nil), state.Fns{Save: (*inodeFileState).save, Load: (*inodeFileState).load}) - state.Register("pkg/sentry/fs/gofer.overrideInfo", (*overrideInfo)(nil), state.Fns{Save: (*overrideInfo).save, Load: (*overrideInfo).load}) - state.Register("pkg/sentry/fs/gofer.overrideMaps", (*overrideMaps)(nil), state.Fns{Save: (*overrideMaps).save, Load: (*overrideMaps).load}) - state.Register("pkg/sentry/fs/gofer.session", (*session)(nil), state.Fns{Save: (*session).save, Load: (*session).load}) + state.Register((*fifo)(nil)) + state.Register((*fileOperations)(nil)) + state.Register((*filesystem)(nil)) + state.Register((*inodeOperations)(nil)) + state.Register((*inodeFileState)(nil)) + state.Register((*overrideInfo)(nil)) + state.Register((*overrideMaps)(nil)) + state.Register((*session)(nil)) } diff --git a/pkg/sentry/fs/host/host_state_autogen.go b/pkg/sentry/fs/host/host_state_autogen.go index a6b97a154..6a1a75ca4 100644 --- a/pkg/sentry/fs/host/host_state_autogen.go +++ b/pkg/sentry/fs/host/host_state_autogen.go @@ -6,112 +6,201 @@ import ( "gvisor.dev/gvisor/pkg/state" ) -func (x *descriptor) save(m state.Map) { +func (x *descriptor) StateTypeName() string { + return "pkg/sentry/fs/host.descriptor" +} + +func (x *descriptor) StateFields() []string { + return []string{ + "origFD", + "wouldBlock", + } +} + +func (x *descriptor) StateSave(m state.Sink) { x.beforeSave() - m.Save("origFD", &x.origFD) - m.Save("wouldBlock", &x.wouldBlock) + m.Save(0, &x.origFD) + m.Save(1, &x.wouldBlock) } -func (x *descriptor) load(m state.Map) { - m.Load("origFD", &x.origFD) - m.Load("wouldBlock", &x.wouldBlock) +func (x *descriptor) StateLoad(m state.Source) { + m.Load(0, &x.origFD) + m.Load(1, &x.wouldBlock) m.AfterLoad(x.afterLoad) } +func (x *fileOperations) StateTypeName() string { + return "pkg/sentry/fs/host.fileOperations" +} + +func (x *fileOperations) StateFields() []string { + return []string{ + "iops", + "dirCursor", + } +} + func (x *fileOperations) beforeSave() {} -func (x *fileOperations) save(m state.Map) { + +func (x *fileOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("iops", &x.iops) - m.Save("dirCursor", &x.dirCursor) + m.Save(0, &x.iops) + m.Save(1, &x.dirCursor) } func (x *fileOperations) afterLoad() {} -func (x *fileOperations) load(m state.Map) { - m.LoadWait("iops", &x.iops) - m.Load("dirCursor", &x.dirCursor) + +func (x *fileOperations) StateLoad(m state.Source) { + m.LoadWait(0, &x.iops) + m.Load(1, &x.dirCursor) +} + +func (x *filesystem) StateTypeName() string { + return "pkg/sentry/fs/host.filesystem" +} + +func (x *filesystem) StateFields() []string { + return []string{} } func (x *filesystem) beforeSave() {} -func (x *filesystem) save(m state.Map) { + +func (x *filesystem) StateSave(m state.Sink) { x.beforeSave() } func (x *filesystem) afterLoad() {} -func (x *filesystem) load(m state.Map) { + +func (x *filesystem) StateLoad(m state.Source) { +} + +func (x *inodeOperations) StateTypeName() string { + return "pkg/sentry/fs/host.inodeOperations" +} + +func (x *inodeOperations) StateFields() []string { + return []string{ + "fileState", + "cachingInodeOps", + } } func (x *inodeOperations) beforeSave() {} -func (x *inodeOperations) save(m state.Map) { + +func (x *inodeOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("fileState", &x.fileState) - m.Save("cachingInodeOps", &x.cachingInodeOps) + m.Save(0, &x.fileState) + m.Save(1, &x.cachingInodeOps) } func (x *inodeOperations) afterLoad() {} -func (x *inodeOperations) load(m state.Map) { - m.LoadWait("fileState", &x.fileState) - m.Load("cachingInodeOps", &x.cachingInodeOps) + +func (x *inodeOperations) StateLoad(m state.Source) { + m.LoadWait(0, &x.fileState) + m.Load(1, &x.cachingInodeOps) +} + +func (x *inodeFileState) StateTypeName() string { + return "pkg/sentry/fs/host.inodeFileState" +} + +func (x *inodeFileState) StateFields() []string { + return []string{ + "descriptor", + "sattr", + "savedUAttr", + } } func (x *inodeFileState) beforeSave() {} -func (x *inodeFileState) save(m state.Map) { + +func (x *inodeFileState) StateSave(m state.Sink) { x.beforeSave() if !state.IsZeroValue(&x.queue) { - m.Failf("queue is %#v, expected zero", &x.queue) + state.Failf("queue is %#v, expected zero", &x.queue) } - m.Save("descriptor", &x.descriptor) - m.Save("sattr", &x.sattr) - m.Save("savedUAttr", &x.savedUAttr) + m.Save(0, &x.descriptor) + m.Save(1, &x.sattr) + m.Save(2, &x.savedUAttr) } -func (x *inodeFileState) load(m state.Map) { - m.LoadWait("descriptor", &x.descriptor) - m.LoadWait("sattr", &x.sattr) - m.Load("savedUAttr", &x.savedUAttr) +func (x *inodeFileState) StateLoad(m state.Source) { + m.LoadWait(0, &x.descriptor) + m.LoadWait(1, &x.sattr) + m.Load(2, &x.savedUAttr) m.AfterLoad(x.afterLoad) } -func (x *ConnectedEndpoint) save(m state.Map) { +func (x *ConnectedEndpoint) StateTypeName() string { + return "pkg/sentry/fs/host.ConnectedEndpoint" +} + +func (x *ConnectedEndpoint) StateFields() []string { + return []string{ + "ref", + "queue", + "path", + "srfd", + "stype", + } +} + +func (x *ConnectedEndpoint) StateSave(m state.Sink) { x.beforeSave() - m.Save("ref", &x.ref) - m.Save("queue", &x.queue) - m.Save("path", &x.path) - m.Save("srfd", &x.srfd) - m.Save("stype", &x.stype) -} - -func (x *ConnectedEndpoint) load(m state.Map) { - m.Load("ref", &x.ref) - m.Load("queue", &x.queue) - m.Load("path", &x.path) - m.LoadWait("srfd", &x.srfd) - m.Load("stype", &x.stype) + m.Save(0, &x.ref) + m.Save(1, &x.queue) + m.Save(2, &x.path) + m.Save(3, &x.srfd) + m.Save(4, &x.stype) +} + +func (x *ConnectedEndpoint) StateLoad(m state.Source) { + m.Load(0, &x.ref) + m.Load(1, &x.queue) + m.Load(2, &x.path) + m.LoadWait(3, &x.srfd) + m.Load(4, &x.stype) m.AfterLoad(x.afterLoad) } +func (x *TTYFileOperations) StateTypeName() string { + return "pkg/sentry/fs/host.TTYFileOperations" +} + +func (x *TTYFileOperations) StateFields() []string { + return []string{ + "fileOperations", + "session", + "fgProcessGroup", + "termios", + } +} + func (x *TTYFileOperations) beforeSave() {} -func (x *TTYFileOperations) save(m state.Map) { + +func (x *TTYFileOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("fileOperations", &x.fileOperations) - m.Save("session", &x.session) - m.Save("fgProcessGroup", &x.fgProcessGroup) - m.Save("termios", &x.termios) + m.Save(0, &x.fileOperations) + m.Save(1, &x.session) + m.Save(2, &x.fgProcessGroup) + m.Save(3, &x.termios) } func (x *TTYFileOperations) afterLoad() {} -func (x *TTYFileOperations) load(m state.Map) { - m.Load("fileOperations", &x.fileOperations) - m.Load("session", &x.session) - m.Load("fgProcessGroup", &x.fgProcessGroup) - m.Load("termios", &x.termios) + +func (x *TTYFileOperations) StateLoad(m state.Source) { + m.Load(0, &x.fileOperations) + m.Load(1, &x.session) + m.Load(2, &x.fgProcessGroup) + m.Load(3, &x.termios) } func init() { - state.Register("pkg/sentry/fs/host.descriptor", (*descriptor)(nil), state.Fns{Save: (*descriptor).save, Load: (*descriptor).load}) - state.Register("pkg/sentry/fs/host.fileOperations", (*fileOperations)(nil), state.Fns{Save: (*fileOperations).save, Load: (*fileOperations).load}) - state.Register("pkg/sentry/fs/host.filesystem", (*filesystem)(nil), state.Fns{Save: (*filesystem).save, Load: (*filesystem).load}) - state.Register("pkg/sentry/fs/host.inodeOperations", (*inodeOperations)(nil), state.Fns{Save: (*inodeOperations).save, Load: (*inodeOperations).load}) - state.Register("pkg/sentry/fs/host.inodeFileState", (*inodeFileState)(nil), state.Fns{Save: (*inodeFileState).save, Load: (*inodeFileState).load}) - state.Register("pkg/sentry/fs/host.ConnectedEndpoint", (*ConnectedEndpoint)(nil), state.Fns{Save: (*ConnectedEndpoint).save, Load: (*ConnectedEndpoint).load}) - state.Register("pkg/sentry/fs/host.TTYFileOperations", (*TTYFileOperations)(nil), state.Fns{Save: (*TTYFileOperations).save, Load: (*TTYFileOperations).load}) + state.Register((*descriptor)(nil)) + state.Register((*fileOperations)(nil)) + state.Register((*filesystem)(nil)) + state.Register((*inodeOperations)(nil)) + state.Register((*inodeFileState)(nil)) + state.Register((*ConnectedEndpoint)(nil)) + state.Register((*TTYFileOperations)(nil)) } diff --git a/pkg/sentry/fs/lock/lock_state_autogen.go b/pkg/sentry/fs/lock/lock_state_autogen.go index 59c493fcb..8e2768c73 100644 --- a/pkg/sentry/fs/lock/lock_state_autogen.go +++ b/pkg/sentry/fs/lock/lock_state_autogen.go @@ -6,103 +6,186 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *Lock) StateTypeName() string { + return "pkg/sentry/fs/lock.Lock" +} + +func (x *Lock) StateFields() []string { + return []string{ + "Readers", + "Writer", + } +} + func (x *Lock) beforeSave() {} -func (x *Lock) save(m state.Map) { + +func (x *Lock) StateSave(m state.Sink) { x.beforeSave() - m.Save("Readers", &x.Readers) - m.Save("Writer", &x.Writer) + m.Save(0, &x.Readers) + m.Save(1, &x.Writer) } func (x *Lock) afterLoad() {} -func (x *Lock) load(m state.Map) { - m.Load("Readers", &x.Readers) - m.Load("Writer", &x.Writer) + +func (x *Lock) StateLoad(m state.Source) { + m.Load(0, &x.Readers) + m.Load(1, &x.Writer) +} + +func (x *Locks) StateTypeName() string { + return "pkg/sentry/fs/lock.Locks" +} + +func (x *Locks) StateFields() []string { + return []string{ + "locks", + } } func (x *Locks) beforeSave() {} -func (x *Locks) save(m state.Map) { + +func (x *Locks) StateSave(m state.Sink) { x.beforeSave() if !state.IsZeroValue(&x.blockedQueue) { - m.Failf("blockedQueue is %#v, expected zero", &x.blockedQueue) + state.Failf("blockedQueue is %#v, expected zero", &x.blockedQueue) } - m.Save("locks", &x.locks) + m.Save(0, &x.locks) } func (x *Locks) afterLoad() {} -func (x *Locks) load(m state.Map) { - m.Load("locks", &x.locks) + +func (x *Locks) StateLoad(m state.Source) { + m.Load(0, &x.locks) +} + +func (x *LockRange) StateTypeName() string { + return "pkg/sentry/fs/lock.LockRange" +} + +func (x *LockRange) StateFields() []string { + return []string{ + "Start", + "End", + } } func (x *LockRange) beforeSave() {} -func (x *LockRange) save(m state.Map) { + +func (x *LockRange) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) + m.Save(0, &x.Start) + m.Save(1, &x.End) } func (x *LockRange) afterLoad() {} -func (x *LockRange) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) + +func (x *LockRange) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) +} + +func (x *LockSet) StateTypeName() string { + return "pkg/sentry/fs/lock.LockSet" +} + +func (x *LockSet) StateFields() []string { + return []string{ + "root", + } } func (x *LockSet) beforeSave() {} -func (x *LockSet) save(m state.Map) { + +func (x *LockSet) StateSave(m state.Sink) { x.beforeSave() var root *LockSegmentDataSlices = x.saveRoot() - m.SaveValue("root", root) + m.SaveValue(0, root) } func (x *LockSet) afterLoad() {} -func (x *LockSet) load(m state.Map) { - m.LoadValue("root", new(*LockSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*LockSegmentDataSlices)) }) + +func (x *LockSet) StateLoad(m state.Source) { + m.LoadValue(0, new(*LockSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*LockSegmentDataSlices)) }) +} + +func (x *Locknode) StateTypeName() string { + return "pkg/sentry/fs/lock.Locknode" +} + +func (x *Locknode) StateFields() []string { + return []string{ + "nrSegments", + "parent", + "parentIndex", + "hasChildren", + "maxGap", + "keys", + "values", + "children", + } } func (x *Locknode) beforeSave() {} -func (x *Locknode) save(m state.Map) { + +func (x *Locknode) StateSave(m state.Sink) { x.beforeSave() - m.Save("nrSegments", &x.nrSegments) - m.Save("parent", &x.parent) - m.Save("parentIndex", &x.parentIndex) - m.Save("hasChildren", &x.hasChildren) - m.Save("maxGap", &x.maxGap) - m.Save("keys", &x.keys) - m.Save("values", &x.values) - m.Save("children", &x.children) + m.Save(0, &x.nrSegments) + m.Save(1, &x.parent) + m.Save(2, &x.parentIndex) + m.Save(3, &x.hasChildren) + m.Save(4, &x.maxGap) + m.Save(5, &x.keys) + m.Save(6, &x.values) + m.Save(7, &x.children) } func (x *Locknode) afterLoad() {} -func (x *Locknode) load(m state.Map) { - m.Load("nrSegments", &x.nrSegments) - m.Load("parent", &x.parent) - m.Load("parentIndex", &x.parentIndex) - m.Load("hasChildren", &x.hasChildren) - m.Load("maxGap", &x.maxGap) - m.Load("keys", &x.keys) - m.Load("values", &x.values) - m.Load("children", &x.children) + +func (x *Locknode) StateLoad(m state.Source) { + m.Load(0, &x.nrSegments) + m.Load(1, &x.parent) + m.Load(2, &x.parentIndex) + m.Load(3, &x.hasChildren) + m.Load(4, &x.maxGap) + m.Load(5, &x.keys) + m.Load(6, &x.values) + m.Load(7, &x.children) +} + +func (x *LockSegmentDataSlices) StateTypeName() string { + return "pkg/sentry/fs/lock.LockSegmentDataSlices" +} + +func (x *LockSegmentDataSlices) StateFields() []string { + return []string{ + "Start", + "End", + "Values", + } } func (x *LockSegmentDataSlices) beforeSave() {} -func (x *LockSegmentDataSlices) save(m state.Map) { + +func (x *LockSegmentDataSlices) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) - m.Save("Values", &x.Values) + m.Save(0, &x.Start) + m.Save(1, &x.End) + m.Save(2, &x.Values) } func (x *LockSegmentDataSlices) afterLoad() {} -func (x *LockSegmentDataSlices) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) - m.Load("Values", &x.Values) + +func (x *LockSegmentDataSlices) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) + m.Load(2, &x.Values) } func init() { - state.Register("pkg/sentry/fs/lock.Lock", (*Lock)(nil), state.Fns{Save: (*Lock).save, Load: (*Lock).load}) - state.Register("pkg/sentry/fs/lock.Locks", (*Locks)(nil), state.Fns{Save: (*Locks).save, Load: (*Locks).load}) - state.Register("pkg/sentry/fs/lock.LockRange", (*LockRange)(nil), state.Fns{Save: (*LockRange).save, Load: (*LockRange).load}) - state.Register("pkg/sentry/fs/lock.LockSet", (*LockSet)(nil), state.Fns{Save: (*LockSet).save, Load: (*LockSet).load}) - state.Register("pkg/sentry/fs/lock.Locknode", (*Locknode)(nil), state.Fns{Save: (*Locknode).save, Load: (*Locknode).load}) - state.Register("pkg/sentry/fs/lock.LockSegmentDataSlices", (*LockSegmentDataSlices)(nil), state.Fns{Save: (*LockSegmentDataSlices).save, Load: (*LockSegmentDataSlices).load}) + state.Register((*Lock)(nil)) + state.Register((*Locks)(nil)) + state.Register((*LockRange)(nil)) + state.Register((*LockSet)(nil)) + state.Register((*Locknode)(nil)) + state.Register((*LockSegmentDataSlices)(nil)) } diff --git a/pkg/sentry/fs/proc/proc_state_autogen.go b/pkg/sentry/fs/proc/proc_state_autogen.go index baf7cd42b..87c979909 100644 --- a/pkg/sentry/fs/proc/proc_state_autogen.go +++ b/pkg/sentry/fs/proc/proc_state_autogen.go @@ -6,736 +6,1430 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *execArgInode) StateTypeName() string { + return "pkg/sentry/fs/proc.execArgInode" +} + +func (x *execArgInode) StateFields() []string { + return []string{ + "SimpleFileInode", + "arg", + "t", + } +} + func (x *execArgInode) beforeSave() {} -func (x *execArgInode) save(m state.Map) { + +func (x *execArgInode) StateSave(m state.Sink) { x.beforeSave() - m.Save("SimpleFileInode", &x.SimpleFileInode) - m.Save("arg", &x.arg) - m.Save("t", &x.t) + m.Save(0, &x.SimpleFileInode) + m.Save(1, &x.arg) + m.Save(2, &x.t) } func (x *execArgInode) afterLoad() {} -func (x *execArgInode) load(m state.Map) { - m.Load("SimpleFileInode", &x.SimpleFileInode) - m.Load("arg", &x.arg) - m.Load("t", &x.t) + +func (x *execArgInode) StateLoad(m state.Source) { + m.Load(0, &x.SimpleFileInode) + m.Load(1, &x.arg) + m.Load(2, &x.t) +} + +func (x *execArgFile) StateTypeName() string { + return "pkg/sentry/fs/proc.execArgFile" +} + +func (x *execArgFile) StateFields() []string { + return []string{ + "arg", + "t", + } } func (x *execArgFile) beforeSave() {} -func (x *execArgFile) save(m state.Map) { + +func (x *execArgFile) StateSave(m state.Sink) { x.beforeSave() - m.Save("arg", &x.arg) - m.Save("t", &x.t) + m.Save(0, &x.arg) + m.Save(1, &x.t) } func (x *execArgFile) afterLoad() {} -func (x *execArgFile) load(m state.Map) { - m.Load("arg", &x.arg) - m.Load("t", &x.t) + +func (x *execArgFile) StateLoad(m state.Source) { + m.Load(0, &x.arg) + m.Load(1, &x.t) +} + +func (x *fdDir) StateTypeName() string { + return "pkg/sentry/fs/proc.fdDir" +} + +func (x *fdDir) StateFields() []string { + return []string{ + "Dir", + "t", + } } func (x *fdDir) beforeSave() {} -func (x *fdDir) save(m state.Map) { + +func (x *fdDir) StateSave(m state.Sink) { x.beforeSave() - m.Save("Dir", &x.Dir) - m.Save("t", &x.t) + m.Save(0, &x.Dir) + m.Save(1, &x.t) } func (x *fdDir) afterLoad() {} -func (x *fdDir) load(m state.Map) { - m.Load("Dir", &x.Dir) - m.Load("t", &x.t) + +func (x *fdDir) StateLoad(m state.Source) { + m.Load(0, &x.Dir) + m.Load(1, &x.t) +} + +func (x *fdDirFile) StateTypeName() string { + return "pkg/sentry/fs/proc.fdDirFile" +} + +func (x *fdDirFile) StateFields() []string { + return []string{ + "isInfoFile", + "t", + } } func (x *fdDirFile) beforeSave() {} -func (x *fdDirFile) save(m state.Map) { + +func (x *fdDirFile) StateSave(m state.Sink) { x.beforeSave() - m.Save("isInfoFile", &x.isInfoFile) - m.Save("t", &x.t) + m.Save(0, &x.isInfoFile) + m.Save(1, &x.t) } func (x *fdDirFile) afterLoad() {} -func (x *fdDirFile) load(m state.Map) { - m.Load("isInfoFile", &x.isInfoFile) - m.Load("t", &x.t) + +func (x *fdDirFile) StateLoad(m state.Source) { + m.Load(0, &x.isInfoFile) + m.Load(1, &x.t) +} + +func (x *fdInfoDir) StateTypeName() string { + return "pkg/sentry/fs/proc.fdInfoDir" +} + +func (x *fdInfoDir) StateFields() []string { + return []string{ + "Dir", + "t", + } } func (x *fdInfoDir) beforeSave() {} -func (x *fdInfoDir) save(m state.Map) { + +func (x *fdInfoDir) StateSave(m state.Sink) { x.beforeSave() - m.Save("Dir", &x.Dir) - m.Save("t", &x.t) + m.Save(0, &x.Dir) + m.Save(1, &x.t) } func (x *fdInfoDir) afterLoad() {} -func (x *fdInfoDir) load(m state.Map) { - m.Load("Dir", &x.Dir) - m.Load("t", &x.t) + +func (x *fdInfoDir) StateLoad(m state.Source) { + m.Load(0, &x.Dir) + m.Load(1, &x.t) +} + +func (x *filesystemsData) StateTypeName() string { + return "pkg/sentry/fs/proc.filesystemsData" +} + +func (x *filesystemsData) StateFields() []string { + return []string{} } func (x *filesystemsData) beforeSave() {} -func (x *filesystemsData) save(m state.Map) { + +func (x *filesystemsData) StateSave(m state.Sink) { x.beforeSave() } func (x *filesystemsData) afterLoad() {} -func (x *filesystemsData) load(m state.Map) { + +func (x *filesystemsData) StateLoad(m state.Source) { +} + +func (x *filesystem) StateTypeName() string { + return "pkg/sentry/fs/proc.filesystem" +} + +func (x *filesystem) StateFields() []string { + return []string{} } func (x *filesystem) beforeSave() {} -func (x *filesystem) save(m state.Map) { + +func (x *filesystem) StateSave(m state.Sink) { x.beforeSave() } func (x *filesystem) afterLoad() {} -func (x *filesystem) load(m state.Map) { + +func (x *filesystem) StateLoad(m state.Source) { +} + +func (x *taskOwnedInodeOps) StateTypeName() string { + return "pkg/sentry/fs/proc.taskOwnedInodeOps" +} + +func (x *taskOwnedInodeOps) StateFields() []string { + return []string{ + "InodeOperations", + "t", + } } func (x *taskOwnedInodeOps) beforeSave() {} -func (x *taskOwnedInodeOps) save(m state.Map) { + +func (x *taskOwnedInodeOps) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeOperations", &x.InodeOperations) - m.Save("t", &x.t) + m.Save(0, &x.InodeOperations) + m.Save(1, &x.t) } func (x *taskOwnedInodeOps) afterLoad() {} -func (x *taskOwnedInodeOps) load(m state.Map) { - m.Load("InodeOperations", &x.InodeOperations) - m.Load("t", &x.t) + +func (x *taskOwnedInodeOps) StateLoad(m state.Source) { + m.Load(0, &x.InodeOperations) + m.Load(1, &x.t) +} + +func (x *staticFileInodeOps) StateTypeName() string { + return "pkg/sentry/fs/proc.staticFileInodeOps" +} + +func (x *staticFileInodeOps) StateFields() []string { + return []string{ + "InodeSimpleAttributes", + "InodeStaticFileGetter", + } } func (x *staticFileInodeOps) beforeSave() {} -func (x *staticFileInodeOps) save(m state.Map) { + +func (x *staticFileInodeOps) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Save("InodeStaticFileGetter", &x.InodeStaticFileGetter) + m.Save(0, &x.InodeSimpleAttributes) + m.Save(1, &x.InodeStaticFileGetter) } func (x *staticFileInodeOps) afterLoad() {} -func (x *staticFileInodeOps) load(m state.Map) { - m.Load("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Load("InodeStaticFileGetter", &x.InodeStaticFileGetter) + +func (x *staticFileInodeOps) StateLoad(m state.Source) { + m.Load(0, &x.InodeSimpleAttributes) + m.Load(1, &x.InodeStaticFileGetter) +} + +func (x *loadavgData) StateTypeName() string { + return "pkg/sentry/fs/proc.loadavgData" +} + +func (x *loadavgData) StateFields() []string { + return []string{} } func (x *loadavgData) beforeSave() {} -func (x *loadavgData) save(m state.Map) { + +func (x *loadavgData) StateSave(m state.Sink) { x.beforeSave() } func (x *loadavgData) afterLoad() {} -func (x *loadavgData) load(m state.Map) { + +func (x *loadavgData) StateLoad(m state.Source) { +} + +func (x *meminfoData) StateTypeName() string { + return "pkg/sentry/fs/proc.meminfoData" +} + +func (x *meminfoData) StateFields() []string { + return []string{ + "k", + } } func (x *meminfoData) beforeSave() {} -func (x *meminfoData) save(m state.Map) { + +func (x *meminfoData) StateSave(m state.Sink) { x.beforeSave() - m.Save("k", &x.k) + m.Save(0, &x.k) } func (x *meminfoData) afterLoad() {} -func (x *meminfoData) load(m state.Map) { - m.Load("k", &x.k) + +func (x *meminfoData) StateLoad(m state.Source) { + m.Load(0, &x.k) +} + +func (x *mountInfoFile) StateTypeName() string { + return "pkg/sentry/fs/proc.mountInfoFile" +} + +func (x *mountInfoFile) StateFields() []string { + return []string{ + "t", + } } func (x *mountInfoFile) beforeSave() {} -func (x *mountInfoFile) save(m state.Map) { + +func (x *mountInfoFile) StateSave(m state.Sink) { x.beforeSave() - m.Save("t", &x.t) + m.Save(0, &x.t) } func (x *mountInfoFile) afterLoad() {} -func (x *mountInfoFile) load(m state.Map) { - m.Load("t", &x.t) + +func (x *mountInfoFile) StateLoad(m state.Source) { + m.Load(0, &x.t) +} + +func (x *mountsFile) StateTypeName() string { + return "pkg/sentry/fs/proc.mountsFile" +} + +func (x *mountsFile) StateFields() []string { + return []string{ + "t", + } } func (x *mountsFile) beforeSave() {} -func (x *mountsFile) save(m state.Map) { + +func (x *mountsFile) StateSave(m state.Sink) { x.beforeSave() - m.Save("t", &x.t) + m.Save(0, &x.t) } func (x *mountsFile) afterLoad() {} -func (x *mountsFile) load(m state.Map) { - m.Load("t", &x.t) + +func (x *mountsFile) StateLoad(m state.Source) { + m.Load(0, &x.t) +} + +func (x *ifinet6) StateTypeName() string { + return "pkg/sentry/fs/proc.ifinet6" +} + +func (x *ifinet6) StateFields() []string { + return []string{ + "s", + } } func (x *ifinet6) beforeSave() {} -func (x *ifinet6) save(m state.Map) { + +func (x *ifinet6) StateSave(m state.Sink) { x.beforeSave() - m.Save("s", &x.s) + m.Save(0, &x.s) } func (x *ifinet6) afterLoad() {} -func (x *ifinet6) load(m state.Map) { - m.Load("s", &x.s) + +func (x *ifinet6) StateLoad(m state.Source) { + m.Load(0, &x.s) +} + +func (x *netDev) StateTypeName() string { + return "pkg/sentry/fs/proc.netDev" +} + +func (x *netDev) StateFields() []string { + return []string{ + "s", + } } func (x *netDev) beforeSave() {} -func (x *netDev) save(m state.Map) { + +func (x *netDev) StateSave(m state.Sink) { x.beforeSave() - m.Save("s", &x.s) + m.Save(0, &x.s) } func (x *netDev) afterLoad() {} -func (x *netDev) load(m state.Map) { - m.Load("s", &x.s) + +func (x *netDev) StateLoad(m state.Source) { + m.Load(0, &x.s) +} + +func (x *netSnmp) StateTypeName() string { + return "pkg/sentry/fs/proc.netSnmp" +} + +func (x *netSnmp) StateFields() []string { + return []string{ + "s", + } } func (x *netSnmp) beforeSave() {} -func (x *netSnmp) save(m state.Map) { + +func (x *netSnmp) StateSave(m state.Sink) { x.beforeSave() - m.Save("s", &x.s) + m.Save(0, &x.s) } func (x *netSnmp) afterLoad() {} -func (x *netSnmp) load(m state.Map) { - m.Load("s", &x.s) + +func (x *netSnmp) StateLoad(m state.Source) { + m.Load(0, &x.s) +} + +func (x *netRoute) StateTypeName() string { + return "pkg/sentry/fs/proc.netRoute" +} + +func (x *netRoute) StateFields() []string { + return []string{ + "s", + } } func (x *netRoute) beforeSave() {} -func (x *netRoute) save(m state.Map) { + +func (x *netRoute) StateSave(m state.Sink) { x.beforeSave() - m.Save("s", &x.s) + m.Save(0, &x.s) } func (x *netRoute) afterLoad() {} -func (x *netRoute) load(m state.Map) { - m.Load("s", &x.s) + +func (x *netRoute) StateLoad(m state.Source) { + m.Load(0, &x.s) +} + +func (x *netUnix) StateTypeName() string { + return "pkg/sentry/fs/proc.netUnix" +} + +func (x *netUnix) StateFields() []string { + return []string{ + "k", + } } func (x *netUnix) beforeSave() {} -func (x *netUnix) save(m state.Map) { + +func (x *netUnix) StateSave(m state.Sink) { x.beforeSave() - m.Save("k", &x.k) + m.Save(0, &x.k) } func (x *netUnix) afterLoad() {} -func (x *netUnix) load(m state.Map) { - m.Load("k", &x.k) + +func (x *netUnix) StateLoad(m state.Source) { + m.Load(0, &x.k) +} + +func (x *netTCP) StateTypeName() string { + return "pkg/sentry/fs/proc.netTCP" +} + +func (x *netTCP) StateFields() []string { + return []string{ + "k", + } } func (x *netTCP) beforeSave() {} -func (x *netTCP) save(m state.Map) { + +func (x *netTCP) StateSave(m state.Sink) { x.beforeSave() - m.Save("k", &x.k) + m.Save(0, &x.k) } func (x *netTCP) afterLoad() {} -func (x *netTCP) load(m state.Map) { - m.Load("k", &x.k) + +func (x *netTCP) StateLoad(m state.Source) { + m.Load(0, &x.k) +} + +func (x *netTCP6) StateTypeName() string { + return "pkg/sentry/fs/proc.netTCP6" +} + +func (x *netTCP6) StateFields() []string { + return []string{ + "k", + } } func (x *netTCP6) beforeSave() {} -func (x *netTCP6) save(m state.Map) { + +func (x *netTCP6) StateSave(m state.Sink) { x.beforeSave() - m.Save("k", &x.k) + m.Save(0, &x.k) } func (x *netTCP6) afterLoad() {} -func (x *netTCP6) load(m state.Map) { - m.Load("k", &x.k) + +func (x *netTCP6) StateLoad(m state.Source) { + m.Load(0, &x.k) +} + +func (x *netUDP) StateTypeName() string { + return "pkg/sentry/fs/proc.netUDP" +} + +func (x *netUDP) StateFields() []string { + return []string{ + "k", + } } func (x *netUDP) beforeSave() {} -func (x *netUDP) save(m state.Map) { + +func (x *netUDP) StateSave(m state.Sink) { x.beforeSave() - m.Save("k", &x.k) + m.Save(0, &x.k) } func (x *netUDP) afterLoad() {} -func (x *netUDP) load(m state.Map) { - m.Load("k", &x.k) + +func (x *netUDP) StateLoad(m state.Source) { + m.Load(0, &x.k) +} + +func (x *proc) StateTypeName() string { + return "pkg/sentry/fs/proc.proc" +} + +func (x *proc) StateFields() []string { + return []string{ + "Dir", + "k", + "pidns", + "cgroupControllers", + } } func (x *proc) beforeSave() {} -func (x *proc) save(m state.Map) { + +func (x *proc) StateSave(m state.Sink) { x.beforeSave() - m.Save("Dir", &x.Dir) - m.Save("k", &x.k) - m.Save("pidns", &x.pidns) - m.Save("cgroupControllers", &x.cgroupControllers) + m.Save(0, &x.Dir) + m.Save(1, &x.k) + m.Save(2, &x.pidns) + m.Save(3, &x.cgroupControllers) } func (x *proc) afterLoad() {} -func (x *proc) load(m state.Map) { - m.Load("Dir", &x.Dir) - m.Load("k", &x.k) - m.Load("pidns", &x.pidns) - m.Load("cgroupControllers", &x.cgroupControllers) + +func (x *proc) StateLoad(m state.Source) { + m.Load(0, &x.Dir) + m.Load(1, &x.k) + m.Load(2, &x.pidns) + m.Load(3, &x.cgroupControllers) +} + +func (x *self) StateTypeName() string { + return "pkg/sentry/fs/proc.self" +} + +func (x *self) StateFields() []string { + return []string{ + "Symlink", + "pidns", + } } func (x *self) beforeSave() {} -func (x *self) save(m state.Map) { + +func (x *self) StateSave(m state.Sink) { x.beforeSave() - m.Save("Symlink", &x.Symlink) - m.Save("pidns", &x.pidns) + m.Save(0, &x.Symlink) + m.Save(1, &x.pidns) } func (x *self) afterLoad() {} -func (x *self) load(m state.Map) { - m.Load("Symlink", &x.Symlink) - m.Load("pidns", &x.pidns) + +func (x *self) StateLoad(m state.Source) { + m.Load(0, &x.Symlink) + m.Load(1, &x.pidns) +} + +func (x *threadSelf) StateTypeName() string { + return "pkg/sentry/fs/proc.threadSelf" +} + +func (x *threadSelf) StateFields() []string { + return []string{ + "Symlink", + "pidns", + } } func (x *threadSelf) beforeSave() {} -func (x *threadSelf) save(m state.Map) { + +func (x *threadSelf) StateSave(m state.Sink) { x.beforeSave() - m.Save("Symlink", &x.Symlink) - m.Save("pidns", &x.pidns) + m.Save(0, &x.Symlink) + m.Save(1, &x.pidns) } func (x *threadSelf) afterLoad() {} -func (x *threadSelf) load(m state.Map) { - m.Load("Symlink", &x.Symlink) - m.Load("pidns", &x.pidns) + +func (x *threadSelf) StateLoad(m state.Source) { + m.Load(0, &x.Symlink) + m.Load(1, &x.pidns) +} + +func (x *rootProcFile) StateTypeName() string { + return "pkg/sentry/fs/proc.rootProcFile" +} + +func (x *rootProcFile) StateFields() []string { + return []string{ + "iops", + } } func (x *rootProcFile) beforeSave() {} -func (x *rootProcFile) save(m state.Map) { + +func (x *rootProcFile) StateSave(m state.Sink) { x.beforeSave() - m.Save("iops", &x.iops) + m.Save(0, &x.iops) } func (x *rootProcFile) afterLoad() {} -func (x *rootProcFile) load(m state.Map) { - m.Load("iops", &x.iops) + +func (x *rootProcFile) StateLoad(m state.Source) { + m.Load(0, &x.iops) +} + +func (x *statData) StateTypeName() string { + return "pkg/sentry/fs/proc.statData" +} + +func (x *statData) StateFields() []string { + return []string{ + "k", + } } func (x *statData) beforeSave() {} -func (x *statData) save(m state.Map) { + +func (x *statData) StateSave(m state.Sink) { x.beforeSave() - m.Save("k", &x.k) + m.Save(0, &x.k) } func (x *statData) afterLoad() {} -func (x *statData) load(m state.Map) { - m.Load("k", &x.k) + +func (x *statData) StateLoad(m state.Source) { + m.Load(0, &x.k) +} + +func (x *mmapMinAddrData) StateTypeName() string { + return "pkg/sentry/fs/proc.mmapMinAddrData" +} + +func (x *mmapMinAddrData) StateFields() []string { + return []string{ + "k", + } } func (x *mmapMinAddrData) beforeSave() {} -func (x *mmapMinAddrData) save(m state.Map) { + +func (x *mmapMinAddrData) StateSave(m state.Sink) { x.beforeSave() - m.Save("k", &x.k) + m.Save(0, &x.k) } func (x *mmapMinAddrData) afterLoad() {} -func (x *mmapMinAddrData) load(m state.Map) { - m.Load("k", &x.k) + +func (x *mmapMinAddrData) StateLoad(m state.Source) { + m.Load(0, &x.k) +} + +func (x *overcommitMemory) StateTypeName() string { + return "pkg/sentry/fs/proc.overcommitMemory" +} + +func (x *overcommitMemory) StateFields() []string { + return []string{} } func (x *overcommitMemory) beforeSave() {} -func (x *overcommitMemory) save(m state.Map) { + +func (x *overcommitMemory) StateSave(m state.Sink) { x.beforeSave() } func (x *overcommitMemory) afterLoad() {} -func (x *overcommitMemory) load(m state.Map) { + +func (x *overcommitMemory) StateLoad(m state.Source) { +} + +func (x *hostname) StateTypeName() string { + return "pkg/sentry/fs/proc.hostname" +} + +func (x *hostname) StateFields() []string { + return []string{ + "SimpleFileInode", + } } func (x *hostname) beforeSave() {} -func (x *hostname) save(m state.Map) { + +func (x *hostname) StateSave(m state.Sink) { x.beforeSave() - m.Save("SimpleFileInode", &x.SimpleFileInode) + m.Save(0, &x.SimpleFileInode) } func (x *hostname) afterLoad() {} -func (x *hostname) load(m state.Map) { - m.Load("SimpleFileInode", &x.SimpleFileInode) + +func (x *hostname) StateLoad(m state.Source) { + m.Load(0, &x.SimpleFileInode) +} + +func (x *hostnameFile) StateTypeName() string { + return "pkg/sentry/fs/proc.hostnameFile" +} + +func (x *hostnameFile) StateFields() []string { + return []string{} } func (x *hostnameFile) beforeSave() {} -func (x *hostnameFile) save(m state.Map) { + +func (x *hostnameFile) StateSave(m state.Sink) { x.beforeSave() } func (x *hostnameFile) afterLoad() {} -func (x *hostnameFile) load(m state.Map) { + +func (x *hostnameFile) StateLoad(m state.Source) { +} + +func (x *tcpMemInode) StateTypeName() string { + return "pkg/sentry/fs/proc.tcpMemInode" +} + +func (x *tcpMemInode) StateFields() []string { + return []string{ + "SimpleFileInode", + "dir", + "s", + "size", + } } -func (x *tcpMemInode) save(m state.Map) { +func (x *tcpMemInode) StateSave(m state.Sink) { x.beforeSave() - m.Save("SimpleFileInode", &x.SimpleFileInode) - m.Save("dir", &x.dir) - m.Save("s", &x.s) - m.Save("size", &x.size) + m.Save(0, &x.SimpleFileInode) + m.Save(1, &x.dir) + m.Save(2, &x.s) + m.Save(3, &x.size) } -func (x *tcpMemInode) load(m state.Map) { - m.Load("SimpleFileInode", &x.SimpleFileInode) - m.Load("dir", &x.dir) - m.LoadWait("s", &x.s) - m.Load("size", &x.size) +func (x *tcpMemInode) StateLoad(m state.Source) { + m.Load(0, &x.SimpleFileInode) + m.Load(1, &x.dir) + m.LoadWait(2, &x.s) + m.Load(3, &x.size) m.AfterLoad(x.afterLoad) } +func (x *tcpMemFile) StateTypeName() string { + return "pkg/sentry/fs/proc.tcpMemFile" +} + +func (x *tcpMemFile) StateFields() []string { + return []string{ + "tcpMemInode", + } +} + func (x *tcpMemFile) beforeSave() {} -func (x *tcpMemFile) save(m state.Map) { + +func (x *tcpMemFile) StateSave(m state.Sink) { x.beforeSave() - m.Save("tcpMemInode", &x.tcpMemInode) + m.Save(0, &x.tcpMemInode) } func (x *tcpMemFile) afterLoad() {} -func (x *tcpMemFile) load(m state.Map) { - m.Load("tcpMemInode", &x.tcpMemInode) + +func (x *tcpMemFile) StateLoad(m state.Source) { + m.Load(0, &x.tcpMemInode) +} + +func (x *tcpSack) StateTypeName() string { + return "pkg/sentry/fs/proc.tcpSack" +} + +func (x *tcpSack) StateFields() []string { + return []string{ + "SimpleFileInode", + "stack", + "enabled", + } } func (x *tcpSack) beforeSave() {} -func (x *tcpSack) save(m state.Map) { + +func (x *tcpSack) StateSave(m state.Sink) { x.beforeSave() - m.Save("SimpleFileInode", &x.SimpleFileInode) - m.Save("stack", &x.stack) - m.Save("enabled", &x.enabled) + m.Save(0, &x.SimpleFileInode) + m.Save(1, &x.stack) + m.Save(2, &x.enabled) } -func (x *tcpSack) load(m state.Map) { - m.Load("SimpleFileInode", &x.SimpleFileInode) - m.LoadWait("stack", &x.stack) - m.Load("enabled", &x.enabled) +func (x *tcpSack) StateLoad(m state.Source) { + m.Load(0, &x.SimpleFileInode) + m.LoadWait(1, &x.stack) + m.Load(2, &x.enabled) m.AfterLoad(x.afterLoad) } +func (x *tcpSackFile) StateTypeName() string { + return "pkg/sentry/fs/proc.tcpSackFile" +} + +func (x *tcpSackFile) StateFields() []string { + return []string{ + "tcpSack", + "stack", + } +} + func (x *tcpSackFile) beforeSave() {} -func (x *tcpSackFile) save(m state.Map) { + +func (x *tcpSackFile) StateSave(m state.Sink) { x.beforeSave() - m.Save("tcpSack", &x.tcpSack) - m.Save("stack", &x.stack) + m.Save(0, &x.tcpSack) + m.Save(1, &x.stack) } func (x *tcpSackFile) afterLoad() {} -func (x *tcpSackFile) load(m state.Map) { - m.Load("tcpSack", &x.tcpSack) - m.LoadWait("stack", &x.stack) + +func (x *tcpSackFile) StateLoad(m state.Source) { + m.Load(0, &x.tcpSack) + m.LoadWait(1, &x.stack) +} + +func (x *taskDir) StateTypeName() string { + return "pkg/sentry/fs/proc.taskDir" +} + +func (x *taskDir) StateFields() []string { + return []string{ + "Dir", + "t", + } } func (x *taskDir) beforeSave() {} -func (x *taskDir) save(m state.Map) { + +func (x *taskDir) StateSave(m state.Sink) { x.beforeSave() - m.Save("Dir", &x.Dir) - m.Save("t", &x.t) + m.Save(0, &x.Dir) + m.Save(1, &x.t) } func (x *taskDir) afterLoad() {} -func (x *taskDir) load(m state.Map) { - m.Load("Dir", &x.Dir) - m.Load("t", &x.t) + +func (x *taskDir) StateLoad(m state.Source) { + m.Load(0, &x.Dir) + m.Load(1, &x.t) +} + +func (x *subtasks) StateTypeName() string { + return "pkg/sentry/fs/proc.subtasks" +} + +func (x *subtasks) StateFields() []string { + return []string{ + "Dir", + "t", + "p", + } } func (x *subtasks) beforeSave() {} -func (x *subtasks) save(m state.Map) { + +func (x *subtasks) StateSave(m state.Sink) { x.beforeSave() - m.Save("Dir", &x.Dir) - m.Save("t", &x.t) - m.Save("p", &x.p) + m.Save(0, &x.Dir) + m.Save(1, &x.t) + m.Save(2, &x.p) } func (x *subtasks) afterLoad() {} -func (x *subtasks) load(m state.Map) { - m.Load("Dir", &x.Dir) - m.Load("t", &x.t) - m.Load("p", &x.p) + +func (x *subtasks) StateLoad(m state.Source) { + m.Load(0, &x.Dir) + m.Load(1, &x.t) + m.Load(2, &x.p) +} + +func (x *subtasksFile) StateTypeName() string { + return "pkg/sentry/fs/proc.subtasksFile" +} + +func (x *subtasksFile) StateFields() []string { + return []string{ + "t", + "pidns", + } } func (x *subtasksFile) beforeSave() {} -func (x *subtasksFile) save(m state.Map) { + +func (x *subtasksFile) StateSave(m state.Sink) { x.beforeSave() - m.Save("t", &x.t) - m.Save("pidns", &x.pidns) + m.Save(0, &x.t) + m.Save(1, &x.pidns) } func (x *subtasksFile) afterLoad() {} -func (x *subtasksFile) load(m state.Map) { - m.Load("t", &x.t) - m.Load("pidns", &x.pidns) + +func (x *subtasksFile) StateLoad(m state.Source) { + m.Load(0, &x.t) + m.Load(1, &x.pidns) +} + +func (x *exe) StateTypeName() string { + return "pkg/sentry/fs/proc.exe" +} + +func (x *exe) StateFields() []string { + return []string{ + "Symlink", + "t", + } } func (x *exe) beforeSave() {} -func (x *exe) save(m state.Map) { + +func (x *exe) StateSave(m state.Sink) { x.beforeSave() - m.Save("Symlink", &x.Symlink) - m.Save("t", &x.t) + m.Save(0, &x.Symlink) + m.Save(1, &x.t) } func (x *exe) afterLoad() {} -func (x *exe) load(m state.Map) { - m.Load("Symlink", &x.Symlink) - m.Load("t", &x.t) + +func (x *exe) StateLoad(m state.Source) { + m.Load(0, &x.Symlink) + m.Load(1, &x.t) +} + +func (x *namespaceSymlink) StateTypeName() string { + return "pkg/sentry/fs/proc.namespaceSymlink" +} + +func (x *namespaceSymlink) StateFields() []string { + return []string{ + "Symlink", + "t", + } } func (x *namespaceSymlink) beforeSave() {} -func (x *namespaceSymlink) save(m state.Map) { + +func (x *namespaceSymlink) StateSave(m state.Sink) { x.beforeSave() - m.Save("Symlink", &x.Symlink) - m.Save("t", &x.t) + m.Save(0, &x.Symlink) + m.Save(1, &x.t) } func (x *namespaceSymlink) afterLoad() {} -func (x *namespaceSymlink) load(m state.Map) { - m.Load("Symlink", &x.Symlink) - m.Load("t", &x.t) + +func (x *namespaceSymlink) StateLoad(m state.Source) { + m.Load(0, &x.Symlink) + m.Load(1, &x.t) +} + +func (x *mapsData) StateTypeName() string { + return "pkg/sentry/fs/proc.mapsData" +} + +func (x *mapsData) StateFields() []string { + return []string{ + "t", + } } func (x *mapsData) beforeSave() {} -func (x *mapsData) save(m state.Map) { + +func (x *mapsData) StateSave(m state.Sink) { x.beforeSave() - m.Save("t", &x.t) + m.Save(0, &x.t) } func (x *mapsData) afterLoad() {} -func (x *mapsData) load(m state.Map) { - m.Load("t", &x.t) + +func (x *mapsData) StateLoad(m state.Source) { + m.Load(0, &x.t) +} + +func (x *smapsData) StateTypeName() string { + return "pkg/sentry/fs/proc.smapsData" +} + +func (x *smapsData) StateFields() []string { + return []string{ + "t", + } } func (x *smapsData) beforeSave() {} -func (x *smapsData) save(m state.Map) { + +func (x *smapsData) StateSave(m state.Sink) { x.beforeSave() - m.Save("t", &x.t) + m.Save(0, &x.t) } func (x *smapsData) afterLoad() {} -func (x *smapsData) load(m state.Map) { - m.Load("t", &x.t) + +func (x *smapsData) StateLoad(m state.Source) { + m.Load(0, &x.t) +} + +func (x *taskStatData) StateTypeName() string { + return "pkg/sentry/fs/proc.taskStatData" +} + +func (x *taskStatData) StateFields() []string { + return []string{ + "t", + "tgstats", + "pidns", + } } func (x *taskStatData) beforeSave() {} -func (x *taskStatData) save(m state.Map) { + +func (x *taskStatData) StateSave(m state.Sink) { x.beforeSave() - m.Save("t", &x.t) - m.Save("tgstats", &x.tgstats) - m.Save("pidns", &x.pidns) + m.Save(0, &x.t) + m.Save(1, &x.tgstats) + m.Save(2, &x.pidns) } func (x *taskStatData) afterLoad() {} -func (x *taskStatData) load(m state.Map) { - m.Load("t", &x.t) - m.Load("tgstats", &x.tgstats) - m.Load("pidns", &x.pidns) + +func (x *taskStatData) StateLoad(m state.Source) { + m.Load(0, &x.t) + m.Load(1, &x.tgstats) + m.Load(2, &x.pidns) +} + +func (x *statmData) StateTypeName() string { + return "pkg/sentry/fs/proc.statmData" +} + +func (x *statmData) StateFields() []string { + return []string{ + "t", + } } func (x *statmData) beforeSave() {} -func (x *statmData) save(m state.Map) { + +func (x *statmData) StateSave(m state.Sink) { x.beforeSave() - m.Save("t", &x.t) + m.Save(0, &x.t) } func (x *statmData) afterLoad() {} -func (x *statmData) load(m state.Map) { - m.Load("t", &x.t) + +func (x *statmData) StateLoad(m state.Source) { + m.Load(0, &x.t) +} + +func (x *statusData) StateTypeName() string { + return "pkg/sentry/fs/proc.statusData" +} + +func (x *statusData) StateFields() []string { + return []string{ + "t", + "pidns", + } } func (x *statusData) beforeSave() {} -func (x *statusData) save(m state.Map) { + +func (x *statusData) StateSave(m state.Sink) { x.beforeSave() - m.Save("t", &x.t) - m.Save("pidns", &x.pidns) + m.Save(0, &x.t) + m.Save(1, &x.pidns) } func (x *statusData) afterLoad() {} -func (x *statusData) load(m state.Map) { - m.Load("t", &x.t) - m.Load("pidns", &x.pidns) + +func (x *statusData) StateLoad(m state.Source) { + m.Load(0, &x.t) + m.Load(1, &x.pidns) +} + +func (x *ioData) StateTypeName() string { + return "pkg/sentry/fs/proc.ioData" +} + +func (x *ioData) StateFields() []string { + return []string{ + "ioUsage", + } } func (x *ioData) beforeSave() {} -func (x *ioData) save(m state.Map) { + +func (x *ioData) StateSave(m state.Sink) { x.beforeSave() - m.Save("ioUsage", &x.ioUsage) + m.Save(0, &x.ioUsage) } func (x *ioData) afterLoad() {} -func (x *ioData) load(m state.Map) { - m.Load("ioUsage", &x.ioUsage) + +func (x *ioData) StateLoad(m state.Source) { + m.Load(0, &x.ioUsage) +} + +func (x *comm) StateTypeName() string { + return "pkg/sentry/fs/proc.comm" +} + +func (x *comm) StateFields() []string { + return []string{ + "SimpleFileInode", + "t", + } } func (x *comm) beforeSave() {} -func (x *comm) save(m state.Map) { + +func (x *comm) StateSave(m state.Sink) { x.beforeSave() - m.Save("SimpleFileInode", &x.SimpleFileInode) - m.Save("t", &x.t) + m.Save(0, &x.SimpleFileInode) + m.Save(1, &x.t) } func (x *comm) afterLoad() {} -func (x *comm) load(m state.Map) { - m.Load("SimpleFileInode", &x.SimpleFileInode) - m.Load("t", &x.t) + +func (x *comm) StateLoad(m state.Source) { + m.Load(0, &x.SimpleFileInode) + m.Load(1, &x.t) +} + +func (x *commFile) StateTypeName() string { + return "pkg/sentry/fs/proc.commFile" +} + +func (x *commFile) StateFields() []string { + return []string{ + "t", + } } func (x *commFile) beforeSave() {} -func (x *commFile) save(m state.Map) { + +func (x *commFile) StateSave(m state.Sink) { x.beforeSave() - m.Save("t", &x.t) + m.Save(0, &x.t) } func (x *commFile) afterLoad() {} -func (x *commFile) load(m state.Map) { - m.Load("t", &x.t) + +func (x *commFile) StateLoad(m state.Source) { + m.Load(0, &x.t) +} + +func (x *auxvec) StateTypeName() string { + return "pkg/sentry/fs/proc.auxvec" +} + +func (x *auxvec) StateFields() []string { + return []string{ + "SimpleFileInode", + "t", + } } func (x *auxvec) beforeSave() {} -func (x *auxvec) save(m state.Map) { + +func (x *auxvec) StateSave(m state.Sink) { x.beforeSave() - m.Save("SimpleFileInode", &x.SimpleFileInode) - m.Save("t", &x.t) + m.Save(0, &x.SimpleFileInode) + m.Save(1, &x.t) } func (x *auxvec) afterLoad() {} -func (x *auxvec) load(m state.Map) { - m.Load("SimpleFileInode", &x.SimpleFileInode) - m.Load("t", &x.t) + +func (x *auxvec) StateLoad(m state.Source) { + m.Load(0, &x.SimpleFileInode) + m.Load(1, &x.t) +} + +func (x *auxvecFile) StateTypeName() string { + return "pkg/sentry/fs/proc.auxvecFile" +} + +func (x *auxvecFile) StateFields() []string { + return []string{ + "t", + } } func (x *auxvecFile) beforeSave() {} -func (x *auxvecFile) save(m state.Map) { + +func (x *auxvecFile) StateSave(m state.Sink) { x.beforeSave() - m.Save("t", &x.t) + m.Save(0, &x.t) } func (x *auxvecFile) afterLoad() {} -func (x *auxvecFile) load(m state.Map) { - m.Load("t", &x.t) + +func (x *auxvecFile) StateLoad(m state.Source) { + m.Load(0, &x.t) +} + +func (x *oomScoreAdj) StateTypeName() string { + return "pkg/sentry/fs/proc.oomScoreAdj" +} + +func (x *oomScoreAdj) StateFields() []string { + return []string{ + "SimpleFileInode", + "t", + } } func (x *oomScoreAdj) beforeSave() {} -func (x *oomScoreAdj) save(m state.Map) { + +func (x *oomScoreAdj) StateSave(m state.Sink) { x.beforeSave() - m.Save("SimpleFileInode", &x.SimpleFileInode) - m.Save("t", &x.t) + m.Save(0, &x.SimpleFileInode) + m.Save(1, &x.t) } func (x *oomScoreAdj) afterLoad() {} -func (x *oomScoreAdj) load(m state.Map) { - m.Load("SimpleFileInode", &x.SimpleFileInode) - m.Load("t", &x.t) + +func (x *oomScoreAdj) StateLoad(m state.Source) { + m.Load(0, &x.SimpleFileInode) + m.Load(1, &x.t) +} + +func (x *oomScoreAdjFile) StateTypeName() string { + return "pkg/sentry/fs/proc.oomScoreAdjFile" +} + +func (x *oomScoreAdjFile) StateFields() []string { + return []string{ + "t", + } } func (x *oomScoreAdjFile) beforeSave() {} -func (x *oomScoreAdjFile) save(m state.Map) { + +func (x *oomScoreAdjFile) StateSave(m state.Sink) { x.beforeSave() - m.Save("t", &x.t) + m.Save(0, &x.t) } func (x *oomScoreAdjFile) afterLoad() {} -func (x *oomScoreAdjFile) load(m state.Map) { - m.Load("t", &x.t) + +func (x *oomScoreAdjFile) StateLoad(m state.Source) { + m.Load(0, &x.t) +} + +func (x *idMapInodeOperations) StateTypeName() string { + return "pkg/sentry/fs/proc.idMapInodeOperations" +} + +func (x *idMapInodeOperations) StateFields() []string { + return []string{ + "InodeSimpleAttributes", + "InodeSimpleExtendedAttributes", + "t", + "gids", + } } func (x *idMapInodeOperations) beforeSave() {} -func (x *idMapInodeOperations) save(m state.Map) { + +func (x *idMapInodeOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Save("InodeSimpleExtendedAttributes", &x.InodeSimpleExtendedAttributes) - m.Save("t", &x.t) - m.Save("gids", &x.gids) + m.Save(0, &x.InodeSimpleAttributes) + m.Save(1, &x.InodeSimpleExtendedAttributes) + m.Save(2, &x.t) + m.Save(3, &x.gids) } func (x *idMapInodeOperations) afterLoad() {} -func (x *idMapInodeOperations) load(m state.Map) { - m.Load("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Load("InodeSimpleExtendedAttributes", &x.InodeSimpleExtendedAttributes) - m.Load("t", &x.t) - m.Load("gids", &x.gids) + +func (x *idMapInodeOperations) StateLoad(m state.Source) { + m.Load(0, &x.InodeSimpleAttributes) + m.Load(1, &x.InodeSimpleExtendedAttributes) + m.Load(2, &x.t) + m.Load(3, &x.gids) +} + +func (x *idMapFileOperations) StateTypeName() string { + return "pkg/sentry/fs/proc.idMapFileOperations" +} + +func (x *idMapFileOperations) StateFields() []string { + return []string{ + "iops", + } } func (x *idMapFileOperations) beforeSave() {} -func (x *idMapFileOperations) save(m state.Map) { + +func (x *idMapFileOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("iops", &x.iops) + m.Save(0, &x.iops) } func (x *idMapFileOperations) afterLoad() {} -func (x *idMapFileOperations) load(m state.Map) { - m.Load("iops", &x.iops) + +func (x *idMapFileOperations) StateLoad(m state.Source) { + m.Load(0, &x.iops) +} + +func (x *uptime) StateTypeName() string { + return "pkg/sentry/fs/proc.uptime" +} + +func (x *uptime) StateFields() []string { + return []string{ + "SimpleFileInode", + "startTime", + } } func (x *uptime) beforeSave() {} -func (x *uptime) save(m state.Map) { + +func (x *uptime) StateSave(m state.Sink) { x.beforeSave() - m.Save("SimpleFileInode", &x.SimpleFileInode) - m.Save("startTime", &x.startTime) + m.Save(0, &x.SimpleFileInode) + m.Save(1, &x.startTime) } func (x *uptime) afterLoad() {} -func (x *uptime) load(m state.Map) { - m.Load("SimpleFileInode", &x.SimpleFileInode) - m.Load("startTime", &x.startTime) + +func (x *uptime) StateLoad(m state.Source) { + m.Load(0, &x.SimpleFileInode) + m.Load(1, &x.startTime) +} + +func (x *uptimeFile) StateTypeName() string { + return "pkg/sentry/fs/proc.uptimeFile" +} + +func (x *uptimeFile) StateFields() []string { + return []string{ + "startTime", + } } func (x *uptimeFile) beforeSave() {} -func (x *uptimeFile) save(m state.Map) { + +func (x *uptimeFile) StateSave(m state.Sink) { x.beforeSave() - m.Save("startTime", &x.startTime) + m.Save(0, &x.startTime) } func (x *uptimeFile) afterLoad() {} -func (x *uptimeFile) load(m state.Map) { - m.Load("startTime", &x.startTime) + +func (x *uptimeFile) StateLoad(m state.Source) { + m.Load(0, &x.startTime) +} + +func (x *versionData) StateTypeName() string { + return "pkg/sentry/fs/proc.versionData" +} + +func (x *versionData) StateFields() []string { + return []string{ + "k", + } } func (x *versionData) beforeSave() {} -func (x *versionData) save(m state.Map) { + +func (x *versionData) StateSave(m state.Sink) { x.beforeSave() - m.Save("k", &x.k) + m.Save(0, &x.k) } func (x *versionData) afterLoad() {} -func (x *versionData) load(m state.Map) { - m.Load("k", &x.k) + +func (x *versionData) StateLoad(m state.Source) { + m.Load(0, &x.k) } func init() { - state.Register("pkg/sentry/fs/proc.execArgInode", (*execArgInode)(nil), state.Fns{Save: (*execArgInode).save, Load: (*execArgInode).load}) - state.Register("pkg/sentry/fs/proc.execArgFile", (*execArgFile)(nil), state.Fns{Save: (*execArgFile).save, Load: (*execArgFile).load}) - state.Register("pkg/sentry/fs/proc.fdDir", (*fdDir)(nil), state.Fns{Save: (*fdDir).save, Load: (*fdDir).load}) - state.Register("pkg/sentry/fs/proc.fdDirFile", (*fdDirFile)(nil), state.Fns{Save: (*fdDirFile).save, Load: (*fdDirFile).load}) - state.Register("pkg/sentry/fs/proc.fdInfoDir", (*fdInfoDir)(nil), state.Fns{Save: (*fdInfoDir).save, Load: (*fdInfoDir).load}) - state.Register("pkg/sentry/fs/proc.filesystemsData", (*filesystemsData)(nil), state.Fns{Save: (*filesystemsData).save, Load: (*filesystemsData).load}) - state.Register("pkg/sentry/fs/proc.filesystem", (*filesystem)(nil), state.Fns{Save: (*filesystem).save, Load: (*filesystem).load}) - state.Register("pkg/sentry/fs/proc.taskOwnedInodeOps", (*taskOwnedInodeOps)(nil), state.Fns{Save: (*taskOwnedInodeOps).save, Load: (*taskOwnedInodeOps).load}) - state.Register("pkg/sentry/fs/proc.staticFileInodeOps", (*staticFileInodeOps)(nil), state.Fns{Save: (*staticFileInodeOps).save, Load: (*staticFileInodeOps).load}) - state.Register("pkg/sentry/fs/proc.loadavgData", (*loadavgData)(nil), state.Fns{Save: (*loadavgData).save, Load: (*loadavgData).load}) - state.Register("pkg/sentry/fs/proc.meminfoData", (*meminfoData)(nil), state.Fns{Save: (*meminfoData).save, Load: (*meminfoData).load}) - state.Register("pkg/sentry/fs/proc.mountInfoFile", (*mountInfoFile)(nil), state.Fns{Save: (*mountInfoFile).save, Load: (*mountInfoFile).load}) - state.Register("pkg/sentry/fs/proc.mountsFile", (*mountsFile)(nil), state.Fns{Save: (*mountsFile).save, Load: (*mountsFile).load}) - state.Register("pkg/sentry/fs/proc.ifinet6", (*ifinet6)(nil), state.Fns{Save: (*ifinet6).save, Load: (*ifinet6).load}) - state.Register("pkg/sentry/fs/proc.netDev", (*netDev)(nil), state.Fns{Save: (*netDev).save, Load: (*netDev).load}) - state.Register("pkg/sentry/fs/proc.netSnmp", (*netSnmp)(nil), state.Fns{Save: (*netSnmp).save, Load: (*netSnmp).load}) - state.Register("pkg/sentry/fs/proc.netRoute", (*netRoute)(nil), state.Fns{Save: (*netRoute).save, Load: (*netRoute).load}) - state.Register("pkg/sentry/fs/proc.netUnix", (*netUnix)(nil), state.Fns{Save: (*netUnix).save, Load: (*netUnix).load}) - state.Register("pkg/sentry/fs/proc.netTCP", (*netTCP)(nil), state.Fns{Save: (*netTCP).save, Load: (*netTCP).load}) - state.Register("pkg/sentry/fs/proc.netTCP6", (*netTCP6)(nil), state.Fns{Save: (*netTCP6).save, Load: (*netTCP6).load}) - state.Register("pkg/sentry/fs/proc.netUDP", (*netUDP)(nil), state.Fns{Save: (*netUDP).save, Load: (*netUDP).load}) - state.Register("pkg/sentry/fs/proc.proc", (*proc)(nil), state.Fns{Save: (*proc).save, Load: (*proc).load}) - state.Register("pkg/sentry/fs/proc.self", (*self)(nil), state.Fns{Save: (*self).save, Load: (*self).load}) - state.Register("pkg/sentry/fs/proc.threadSelf", (*threadSelf)(nil), state.Fns{Save: (*threadSelf).save, Load: (*threadSelf).load}) - state.Register("pkg/sentry/fs/proc.rootProcFile", (*rootProcFile)(nil), state.Fns{Save: (*rootProcFile).save, Load: (*rootProcFile).load}) - state.Register("pkg/sentry/fs/proc.statData", (*statData)(nil), state.Fns{Save: (*statData).save, Load: (*statData).load}) - state.Register("pkg/sentry/fs/proc.mmapMinAddrData", (*mmapMinAddrData)(nil), state.Fns{Save: (*mmapMinAddrData).save, Load: (*mmapMinAddrData).load}) - state.Register("pkg/sentry/fs/proc.overcommitMemory", (*overcommitMemory)(nil), state.Fns{Save: (*overcommitMemory).save, Load: (*overcommitMemory).load}) - state.Register("pkg/sentry/fs/proc.hostname", (*hostname)(nil), state.Fns{Save: (*hostname).save, Load: (*hostname).load}) - state.Register("pkg/sentry/fs/proc.hostnameFile", (*hostnameFile)(nil), state.Fns{Save: (*hostnameFile).save, Load: (*hostnameFile).load}) - state.Register("pkg/sentry/fs/proc.tcpMemInode", (*tcpMemInode)(nil), state.Fns{Save: (*tcpMemInode).save, Load: (*tcpMemInode).load}) - state.Register("pkg/sentry/fs/proc.tcpMemFile", (*tcpMemFile)(nil), state.Fns{Save: (*tcpMemFile).save, Load: (*tcpMemFile).load}) - state.Register("pkg/sentry/fs/proc.tcpSack", (*tcpSack)(nil), state.Fns{Save: (*tcpSack).save, Load: (*tcpSack).load}) - state.Register("pkg/sentry/fs/proc.tcpSackFile", (*tcpSackFile)(nil), state.Fns{Save: (*tcpSackFile).save, Load: (*tcpSackFile).load}) - state.Register("pkg/sentry/fs/proc.taskDir", (*taskDir)(nil), state.Fns{Save: (*taskDir).save, Load: (*taskDir).load}) - state.Register("pkg/sentry/fs/proc.subtasks", (*subtasks)(nil), state.Fns{Save: (*subtasks).save, Load: (*subtasks).load}) - state.Register("pkg/sentry/fs/proc.subtasksFile", (*subtasksFile)(nil), state.Fns{Save: (*subtasksFile).save, Load: (*subtasksFile).load}) - state.Register("pkg/sentry/fs/proc.exe", (*exe)(nil), state.Fns{Save: (*exe).save, Load: (*exe).load}) - state.Register("pkg/sentry/fs/proc.namespaceSymlink", (*namespaceSymlink)(nil), state.Fns{Save: (*namespaceSymlink).save, Load: (*namespaceSymlink).load}) - state.Register("pkg/sentry/fs/proc.mapsData", (*mapsData)(nil), state.Fns{Save: (*mapsData).save, Load: (*mapsData).load}) - state.Register("pkg/sentry/fs/proc.smapsData", (*smapsData)(nil), state.Fns{Save: (*smapsData).save, Load: (*smapsData).load}) - state.Register("pkg/sentry/fs/proc.taskStatData", (*taskStatData)(nil), state.Fns{Save: (*taskStatData).save, Load: (*taskStatData).load}) - state.Register("pkg/sentry/fs/proc.statmData", (*statmData)(nil), state.Fns{Save: (*statmData).save, Load: (*statmData).load}) - state.Register("pkg/sentry/fs/proc.statusData", (*statusData)(nil), state.Fns{Save: (*statusData).save, Load: (*statusData).load}) - state.Register("pkg/sentry/fs/proc.ioData", (*ioData)(nil), state.Fns{Save: (*ioData).save, Load: (*ioData).load}) - state.Register("pkg/sentry/fs/proc.comm", (*comm)(nil), state.Fns{Save: (*comm).save, Load: (*comm).load}) - state.Register("pkg/sentry/fs/proc.commFile", (*commFile)(nil), state.Fns{Save: (*commFile).save, Load: (*commFile).load}) - state.Register("pkg/sentry/fs/proc.auxvec", (*auxvec)(nil), state.Fns{Save: (*auxvec).save, Load: (*auxvec).load}) - state.Register("pkg/sentry/fs/proc.auxvecFile", (*auxvecFile)(nil), state.Fns{Save: (*auxvecFile).save, Load: (*auxvecFile).load}) - state.Register("pkg/sentry/fs/proc.oomScoreAdj", (*oomScoreAdj)(nil), state.Fns{Save: (*oomScoreAdj).save, Load: (*oomScoreAdj).load}) - state.Register("pkg/sentry/fs/proc.oomScoreAdjFile", (*oomScoreAdjFile)(nil), state.Fns{Save: (*oomScoreAdjFile).save, Load: (*oomScoreAdjFile).load}) - state.Register("pkg/sentry/fs/proc.idMapInodeOperations", (*idMapInodeOperations)(nil), state.Fns{Save: (*idMapInodeOperations).save, Load: (*idMapInodeOperations).load}) - state.Register("pkg/sentry/fs/proc.idMapFileOperations", (*idMapFileOperations)(nil), state.Fns{Save: (*idMapFileOperations).save, Load: (*idMapFileOperations).load}) - state.Register("pkg/sentry/fs/proc.uptime", (*uptime)(nil), state.Fns{Save: (*uptime).save, Load: (*uptime).load}) - state.Register("pkg/sentry/fs/proc.uptimeFile", (*uptimeFile)(nil), state.Fns{Save: (*uptimeFile).save, Load: (*uptimeFile).load}) - state.Register("pkg/sentry/fs/proc.versionData", (*versionData)(nil), state.Fns{Save: (*versionData).save, Load: (*versionData).load}) + 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((*taskDir)(nil)) + state.Register((*subtasks)(nil)) + state.Register((*subtasksFile)(nil)) + state.Register((*exe)(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/seqfile_state_autogen.go b/pkg/sentry/fs/proc/seqfile/seqfile_state_autogen.go index cfd3a40b4..6f48a944a 100644 --- a/pkg/sentry/fs/proc/seqfile/seqfile_state_autogen.go +++ b/pkg/sentry/fs/proc/seqfile/seqfile_state_autogen.go @@ -6,53 +6,95 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *SeqData) StateTypeName() string { + return "pkg/sentry/fs/proc/seqfile.SeqData" +} + +func (x *SeqData) StateFields() []string { + return []string{ + "Buf", + "Handle", + } +} + func (x *SeqData) beforeSave() {} -func (x *SeqData) save(m state.Map) { + +func (x *SeqData) StateSave(m state.Sink) { x.beforeSave() - m.Save("Buf", &x.Buf) - m.Save("Handle", &x.Handle) + m.Save(0, &x.Buf) + m.Save(1, &x.Handle) } func (x *SeqData) afterLoad() {} -func (x *SeqData) load(m state.Map) { - m.Load("Buf", &x.Buf) - m.Load("Handle", &x.Handle) + +func (x *SeqData) StateLoad(m state.Source) { + m.Load(0, &x.Buf) + m.Load(1, &x.Handle) +} + +func (x *SeqFile) StateTypeName() string { + return "pkg/sentry/fs/proc/seqfile.SeqFile" +} + +func (x *SeqFile) StateFields() []string { + return []string{ + "InodeSimpleExtendedAttributes", + "InodeSimpleAttributes", + "SeqSource", + "source", + "generation", + "lastRead", + } } func (x *SeqFile) beforeSave() {} -func (x *SeqFile) save(m state.Map) { + +func (x *SeqFile) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeSimpleExtendedAttributes", &x.InodeSimpleExtendedAttributes) - m.Save("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Save("SeqSource", &x.SeqSource) - m.Save("source", &x.source) - m.Save("generation", &x.generation) - m.Save("lastRead", &x.lastRead) + m.Save(0, &x.InodeSimpleExtendedAttributes) + m.Save(1, &x.InodeSimpleAttributes) + m.Save(2, &x.SeqSource) + m.Save(3, &x.source) + m.Save(4, &x.generation) + m.Save(5, &x.lastRead) } func (x *SeqFile) afterLoad() {} -func (x *SeqFile) load(m state.Map) { - m.Load("InodeSimpleExtendedAttributes", &x.InodeSimpleExtendedAttributes) - m.Load("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Load("SeqSource", &x.SeqSource) - m.Load("source", &x.source) - m.Load("generation", &x.generation) - m.Load("lastRead", &x.lastRead) + +func (x *SeqFile) StateLoad(m state.Source) { + m.Load(0, &x.InodeSimpleExtendedAttributes) + m.Load(1, &x.InodeSimpleAttributes) + m.Load(2, &x.SeqSource) + m.Load(3, &x.source) + m.Load(4, &x.generation) + m.Load(5, &x.lastRead) +} + +func (x *seqFileOperations) StateTypeName() string { + return "pkg/sentry/fs/proc/seqfile.seqFileOperations" +} + +func (x *seqFileOperations) StateFields() []string { + return []string{ + "seqFile", + } } func (x *seqFileOperations) beforeSave() {} -func (x *seqFileOperations) save(m state.Map) { + +func (x *seqFileOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("seqFile", &x.seqFile) + m.Save(0, &x.seqFile) } func (x *seqFileOperations) afterLoad() {} -func (x *seqFileOperations) load(m state.Map) { - m.Load("seqFile", &x.seqFile) + +func (x *seqFileOperations) StateLoad(m state.Source) { + m.Load(0, &x.seqFile) } func init() { - state.Register("pkg/sentry/fs/proc/seqfile.SeqData", (*SeqData)(nil), state.Fns{Save: (*SeqData).save, Load: (*SeqData).load}) - state.Register("pkg/sentry/fs/proc/seqfile.SeqFile", (*SeqFile)(nil), state.Fns{Save: (*SeqFile).save, Load: (*SeqFile).load}) - state.Register("pkg/sentry/fs/proc/seqfile.seqFileOperations", (*seqFileOperations)(nil), state.Fns{Save: (*seqFileOperations).save, Load: (*seqFileOperations).load}) + state.Register((*SeqData)(nil)) + state.Register((*SeqFile)(nil)) + state.Register((*seqFileOperations)(nil)) } diff --git a/pkg/sentry/fs/ramfs/ramfs_state_autogen.go b/pkg/sentry/fs/ramfs/ramfs_state_autogen.go index 0a001e0b6..bfa355c84 100644 --- a/pkg/sentry/fs/ramfs/ramfs_state_autogen.go +++ b/pkg/sentry/fs/ramfs/ramfs_state_autogen.go @@ -6,89 +6,165 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *Dir) StateTypeName() string { + return "pkg/sentry/fs/ramfs.Dir" +} + +func (x *Dir) StateFields() []string { + return []string{ + "InodeSimpleAttributes", + "InodeSimpleExtendedAttributes", + "children", + "dentryMap", + } +} + func (x *Dir) beforeSave() {} -func (x *Dir) save(m state.Map) { + +func (x *Dir) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Save("InodeSimpleExtendedAttributes", &x.InodeSimpleExtendedAttributes) - m.Save("children", &x.children) - m.Save("dentryMap", &x.dentryMap) + m.Save(0, &x.InodeSimpleAttributes) + m.Save(1, &x.InodeSimpleExtendedAttributes) + m.Save(2, &x.children) + m.Save(3, &x.dentryMap) } func (x *Dir) afterLoad() {} -func (x *Dir) load(m state.Map) { - m.Load("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Load("InodeSimpleExtendedAttributes", &x.InodeSimpleExtendedAttributes) - m.Load("children", &x.children) - m.Load("dentryMap", &x.dentryMap) + +func (x *Dir) StateLoad(m state.Source) { + m.Load(0, &x.InodeSimpleAttributes) + m.Load(1, &x.InodeSimpleExtendedAttributes) + m.Load(2, &x.children) + m.Load(3, &x.dentryMap) +} + +func (x *dirFileOperations) StateTypeName() string { + return "pkg/sentry/fs/ramfs.dirFileOperations" +} + +func (x *dirFileOperations) StateFields() []string { + return []string{ + "dirCursor", + "dir", + } } func (x *dirFileOperations) beforeSave() {} -func (x *dirFileOperations) save(m state.Map) { + +func (x *dirFileOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("dirCursor", &x.dirCursor) - m.Save("dir", &x.dir) + m.Save(0, &x.dirCursor) + m.Save(1, &x.dir) } func (x *dirFileOperations) afterLoad() {} -func (x *dirFileOperations) load(m state.Map) { - m.Load("dirCursor", &x.dirCursor) - m.Load("dir", &x.dir) + +func (x *dirFileOperations) StateLoad(m state.Source) { + m.Load(0, &x.dirCursor) + m.Load(1, &x.dir) +} + +func (x *Socket) StateTypeName() string { + return "pkg/sentry/fs/ramfs.Socket" +} + +func (x *Socket) StateFields() []string { + return []string{ + "InodeSimpleAttributes", + "InodeSimpleExtendedAttributes", + "ep", + } } func (x *Socket) beforeSave() {} -func (x *Socket) save(m state.Map) { + +func (x *Socket) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Save("InodeSimpleExtendedAttributes", &x.InodeSimpleExtendedAttributes) - m.Save("ep", &x.ep) + m.Save(0, &x.InodeSimpleAttributes) + m.Save(1, &x.InodeSimpleExtendedAttributes) + m.Save(2, &x.ep) } func (x *Socket) afterLoad() {} -func (x *Socket) load(m state.Map) { - m.Load("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Load("InodeSimpleExtendedAttributes", &x.InodeSimpleExtendedAttributes) - m.Load("ep", &x.ep) + +func (x *Socket) StateLoad(m state.Source) { + m.Load(0, &x.InodeSimpleAttributes) + m.Load(1, &x.InodeSimpleExtendedAttributes) + m.Load(2, &x.ep) +} + +func (x *socketFileOperations) StateTypeName() string { + return "pkg/sentry/fs/ramfs.socketFileOperations" +} + +func (x *socketFileOperations) StateFields() []string { + return []string{} } func (x *socketFileOperations) beforeSave() {} -func (x *socketFileOperations) save(m state.Map) { + +func (x *socketFileOperations) StateSave(m state.Sink) { x.beforeSave() } func (x *socketFileOperations) afterLoad() {} -func (x *socketFileOperations) load(m state.Map) { + +func (x *socketFileOperations) StateLoad(m state.Source) { +} + +func (x *Symlink) StateTypeName() string { + return "pkg/sentry/fs/ramfs.Symlink" +} + +func (x *Symlink) StateFields() []string { + return []string{ + "InodeSimpleAttributes", + "InodeSimpleExtendedAttributes", + "Target", + } } func (x *Symlink) beforeSave() {} -func (x *Symlink) save(m state.Map) { + +func (x *Symlink) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Save("InodeSimpleExtendedAttributes", &x.InodeSimpleExtendedAttributes) - m.Save("Target", &x.Target) + m.Save(0, &x.InodeSimpleAttributes) + m.Save(1, &x.InodeSimpleExtendedAttributes) + m.Save(2, &x.Target) } func (x *Symlink) afterLoad() {} -func (x *Symlink) load(m state.Map) { - m.Load("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Load("InodeSimpleExtendedAttributes", &x.InodeSimpleExtendedAttributes) - m.Load("Target", &x.Target) + +func (x *Symlink) StateLoad(m state.Source) { + m.Load(0, &x.InodeSimpleAttributes) + m.Load(1, &x.InodeSimpleExtendedAttributes) + m.Load(2, &x.Target) +} + +func (x *symlinkFileOperations) StateTypeName() string { + return "pkg/sentry/fs/ramfs.symlinkFileOperations" +} + +func (x *symlinkFileOperations) StateFields() []string { + return []string{} } func (x *symlinkFileOperations) beforeSave() {} -func (x *symlinkFileOperations) save(m state.Map) { + +func (x *symlinkFileOperations) StateSave(m state.Sink) { x.beforeSave() } func (x *symlinkFileOperations) afterLoad() {} -func (x *symlinkFileOperations) load(m state.Map) { + +func (x *symlinkFileOperations) StateLoad(m state.Source) { } func init() { - state.Register("pkg/sentry/fs/ramfs.Dir", (*Dir)(nil), state.Fns{Save: (*Dir).save, Load: (*Dir).load}) - state.Register("pkg/sentry/fs/ramfs.dirFileOperations", (*dirFileOperations)(nil), state.Fns{Save: (*dirFileOperations).save, Load: (*dirFileOperations).load}) - state.Register("pkg/sentry/fs/ramfs.Socket", (*Socket)(nil), state.Fns{Save: (*Socket).save, Load: (*Socket).load}) - state.Register("pkg/sentry/fs/ramfs.socketFileOperations", (*socketFileOperations)(nil), state.Fns{Save: (*socketFileOperations).save, Load: (*socketFileOperations).load}) - state.Register("pkg/sentry/fs/ramfs.Symlink", (*Symlink)(nil), state.Fns{Save: (*Symlink).save, Load: (*Symlink).load}) - state.Register("pkg/sentry/fs/ramfs.symlinkFileOperations", (*symlinkFileOperations)(nil), state.Fns{Save: (*symlinkFileOperations).save, Load: (*symlinkFileOperations).load}) + state.Register((*Dir)(nil)) + state.Register((*dirFileOperations)(nil)) + state.Register((*Socket)(nil)) + state.Register((*socketFileOperations)(nil)) + state.Register((*Symlink)(nil)) + state.Register((*symlinkFileOperations)(nil)) } diff --git a/pkg/sentry/fs/sys/sys_state_autogen.go b/pkg/sentry/fs/sys/sys_state_autogen.go index 733c504b1..71e08a167 100644 --- a/pkg/sentry/fs/sys/sys_state_autogen.go +++ b/pkg/sentry/fs/sys/sys_state_autogen.go @@ -6,29 +6,52 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *cpunum) StateTypeName() string { + return "pkg/sentry/fs/sys.cpunum" +} + +func (x *cpunum) StateFields() []string { + return []string{ + "InodeSimpleAttributes", + "InodeStaticFileGetter", + } +} + func (x *cpunum) beforeSave() {} -func (x *cpunum) save(m state.Map) { + +func (x *cpunum) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Save("InodeStaticFileGetter", &x.InodeStaticFileGetter) + m.Save(0, &x.InodeSimpleAttributes) + m.Save(1, &x.InodeStaticFileGetter) } func (x *cpunum) afterLoad() {} -func (x *cpunum) load(m state.Map) { - m.Load("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Load("InodeStaticFileGetter", &x.InodeStaticFileGetter) + +func (x *cpunum) StateLoad(m state.Source) { + m.Load(0, &x.InodeSimpleAttributes) + m.Load(1, &x.InodeStaticFileGetter) +} + +func (x *filesystem) StateTypeName() string { + return "pkg/sentry/fs/sys.filesystem" +} + +func (x *filesystem) StateFields() []string { + return []string{} } func (x *filesystem) beforeSave() {} -func (x *filesystem) save(m state.Map) { + +func (x *filesystem) StateSave(m state.Sink) { x.beforeSave() } func (x *filesystem) afterLoad() {} -func (x *filesystem) load(m state.Map) { + +func (x *filesystem) StateLoad(m state.Source) { } func init() { - state.Register("pkg/sentry/fs/sys.cpunum", (*cpunum)(nil), state.Fns{Save: (*cpunum).save, Load: (*cpunum).load}) - state.Register("pkg/sentry/fs/sys.filesystem", (*filesystem)(nil), state.Fns{Save: (*filesystem).save, Load: (*filesystem).load}) + state.Register((*cpunum)(nil)) + state.Register((*filesystem)(nil)) } diff --git a/pkg/sentry/fs/timerfd/timerfd_state_autogen.go b/pkg/sentry/fs/timerfd/timerfd_state_autogen.go index 955cf1d38..2a411ceab 100644 --- a/pkg/sentry/fs/timerfd/timerfd_state_autogen.go +++ b/pkg/sentry/fs/timerfd/timerfd_state_autogen.go @@ -6,22 +6,35 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *TimerOperations) StateTypeName() string { + return "pkg/sentry/fs/timerfd.TimerOperations" +} + +func (x *TimerOperations) StateFields() []string { + return []string{ + "timer", + "val", + } +} + func (x *TimerOperations) beforeSave() {} -func (x *TimerOperations) save(m state.Map) { + +func (x *TimerOperations) StateSave(m state.Sink) { x.beforeSave() if !state.IsZeroValue(&x.events) { - m.Failf("events is %#v, expected zero", &x.events) + state.Failf("events is %#v, expected zero", &x.events) } - m.Save("timer", &x.timer) - m.Save("val", &x.val) + m.Save(0, &x.timer) + m.Save(1, &x.val) } func (x *TimerOperations) afterLoad() {} -func (x *TimerOperations) load(m state.Map) { - m.Load("timer", &x.timer) - m.Load("val", &x.val) + +func (x *TimerOperations) StateLoad(m state.Source) { + m.Load(0, &x.timer) + m.Load(1, &x.val) } func init() { - state.Register("pkg/sentry/fs/timerfd.TimerOperations", (*TimerOperations)(nil), state.Fns{Save: (*TimerOperations).save, Load: (*TimerOperations).load}) + state.Register((*TimerOperations)(nil)) } diff --git a/pkg/sentry/fs/tmpfs/tmpfs_state_autogen.go b/pkg/sentry/fs/tmpfs/tmpfs_state_autogen.go index e4d2584fd..894d3679e 100644 --- a/pkg/sentry/fs/tmpfs/tmpfs_state_autogen.go +++ b/pkg/sentry/fs/tmpfs/tmpfs_state_autogen.go @@ -6,103 +6,192 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *regularFileOperations) StateTypeName() string { + return "pkg/sentry/fs/tmpfs.regularFileOperations" +} + +func (x *regularFileOperations) StateFields() []string { + return []string{ + "iops", + } +} + func (x *regularFileOperations) beforeSave() {} -func (x *regularFileOperations) save(m state.Map) { + +func (x *regularFileOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("iops", &x.iops) + m.Save(0, &x.iops) } func (x *regularFileOperations) afterLoad() {} -func (x *regularFileOperations) load(m state.Map) { - m.Load("iops", &x.iops) + +func (x *regularFileOperations) StateLoad(m state.Source) { + m.Load(0, &x.iops) +} + +func (x *Filesystem) StateTypeName() string { + return "pkg/sentry/fs/tmpfs.Filesystem" +} + +func (x *Filesystem) StateFields() []string { + return []string{} } func (x *Filesystem) beforeSave() {} -func (x *Filesystem) save(m state.Map) { + +func (x *Filesystem) StateSave(m state.Sink) { x.beforeSave() } func (x *Filesystem) afterLoad() {} -func (x *Filesystem) load(m state.Map) { + +func (x *Filesystem) StateLoad(m state.Source) { +} + +func (x *fileInodeOperations) StateTypeName() string { + return "pkg/sentry/fs/tmpfs.fileInodeOperations" +} + +func (x *fileInodeOperations) StateFields() []string { + return []string{ + "InodeSimpleExtendedAttributes", + "kernel", + "memUsage", + "attr", + "mappings", + "writableMappingPages", + "data", + "seals", + } } func (x *fileInodeOperations) beforeSave() {} -func (x *fileInodeOperations) save(m state.Map) { + +func (x *fileInodeOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeSimpleExtendedAttributes", &x.InodeSimpleExtendedAttributes) - m.Save("kernel", &x.kernel) - m.Save("memUsage", &x.memUsage) - m.Save("attr", &x.attr) - m.Save("mappings", &x.mappings) - m.Save("writableMappingPages", &x.writableMappingPages) - m.Save("data", &x.data) - m.Save("seals", &x.seals) + m.Save(0, &x.InodeSimpleExtendedAttributes) + m.Save(1, &x.kernel) + m.Save(2, &x.memUsage) + m.Save(3, &x.attr) + m.Save(4, &x.mappings) + m.Save(5, &x.writableMappingPages) + m.Save(6, &x.data) + m.Save(7, &x.seals) } func (x *fileInodeOperations) afterLoad() {} -func (x *fileInodeOperations) load(m state.Map) { - m.Load("InodeSimpleExtendedAttributes", &x.InodeSimpleExtendedAttributes) - m.Load("kernel", &x.kernel) - m.Load("memUsage", &x.memUsage) - m.Load("attr", &x.attr) - m.Load("mappings", &x.mappings) - m.Load("writableMappingPages", &x.writableMappingPages) - m.Load("data", &x.data) - m.Load("seals", &x.seals) + +func (x *fileInodeOperations) StateLoad(m state.Source) { + m.Load(0, &x.InodeSimpleExtendedAttributes) + m.Load(1, &x.kernel) + m.Load(2, &x.memUsage) + m.Load(3, &x.attr) + m.Load(4, &x.mappings) + m.Load(5, &x.writableMappingPages) + m.Load(6, &x.data) + m.Load(7, &x.seals) +} + +func (x *Dir) StateTypeName() string { + return "pkg/sentry/fs/tmpfs.Dir" +} + +func (x *Dir) StateFields() []string { + return []string{ + "ramfsDir", + "kernel", + } } func (x *Dir) beforeSave() {} -func (x *Dir) save(m state.Map) { + +func (x *Dir) StateSave(m state.Sink) { x.beforeSave() - m.Save("ramfsDir", &x.ramfsDir) - m.Save("kernel", &x.kernel) + m.Save(0, &x.ramfsDir) + m.Save(1, &x.kernel) } -func (x *Dir) load(m state.Map) { - m.Load("ramfsDir", &x.ramfsDir) - m.Load("kernel", &x.kernel) +func (x *Dir) StateLoad(m state.Source) { + m.Load(0, &x.ramfsDir) + m.Load(1, &x.kernel) m.AfterLoad(x.afterLoad) } +func (x *Symlink) StateTypeName() string { + return "pkg/sentry/fs/tmpfs.Symlink" +} + +func (x *Symlink) StateFields() []string { + return []string{ + "Symlink", + } +} + func (x *Symlink) beforeSave() {} -func (x *Symlink) save(m state.Map) { + +func (x *Symlink) StateSave(m state.Sink) { x.beforeSave() - m.Save("Symlink", &x.Symlink) + m.Save(0, &x.Symlink) } func (x *Symlink) afterLoad() {} -func (x *Symlink) load(m state.Map) { - m.Load("Symlink", &x.Symlink) + +func (x *Symlink) StateLoad(m state.Source) { + m.Load(0, &x.Symlink) +} + +func (x *Socket) StateTypeName() string { + return "pkg/sentry/fs/tmpfs.Socket" +} + +func (x *Socket) StateFields() []string { + return []string{ + "Socket", + } } func (x *Socket) beforeSave() {} -func (x *Socket) save(m state.Map) { + +func (x *Socket) StateSave(m state.Sink) { x.beforeSave() - m.Save("Socket", &x.Socket) + m.Save(0, &x.Socket) } func (x *Socket) afterLoad() {} -func (x *Socket) load(m state.Map) { - m.Load("Socket", &x.Socket) + +func (x *Socket) StateLoad(m state.Source) { + m.Load(0, &x.Socket) +} + +func (x *Fifo) StateTypeName() string { + return "pkg/sentry/fs/tmpfs.Fifo" +} + +func (x *Fifo) StateFields() []string { + return []string{ + "InodeOperations", + } } func (x *Fifo) beforeSave() {} -func (x *Fifo) save(m state.Map) { + +func (x *Fifo) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeOperations", &x.InodeOperations) + m.Save(0, &x.InodeOperations) } func (x *Fifo) afterLoad() {} -func (x *Fifo) load(m state.Map) { - m.Load("InodeOperations", &x.InodeOperations) + +func (x *Fifo) StateLoad(m state.Source) { + m.Load(0, &x.InodeOperations) } func init() { - state.Register("pkg/sentry/fs/tmpfs.regularFileOperations", (*regularFileOperations)(nil), state.Fns{Save: (*regularFileOperations).save, Load: (*regularFileOperations).load}) - state.Register("pkg/sentry/fs/tmpfs.Filesystem", (*Filesystem)(nil), state.Fns{Save: (*Filesystem).save, Load: (*Filesystem).load}) - state.Register("pkg/sentry/fs/tmpfs.fileInodeOperations", (*fileInodeOperations)(nil), state.Fns{Save: (*fileInodeOperations).save, Load: (*fileInodeOperations).load}) - state.Register("pkg/sentry/fs/tmpfs.Dir", (*Dir)(nil), state.Fns{Save: (*Dir).save, Load: (*Dir).load}) - state.Register("pkg/sentry/fs/tmpfs.Symlink", (*Symlink)(nil), state.Fns{Save: (*Symlink).save, Load: (*Symlink).load}) - state.Register("pkg/sentry/fs/tmpfs.Socket", (*Socket)(nil), state.Fns{Save: (*Socket).save, Load: (*Socket).load}) - state.Register("pkg/sentry/fs/tmpfs.Fifo", (*Fifo)(nil), state.Fns{Save: (*Fifo).save, Load: (*Fifo).load}) + state.Register((*regularFileOperations)(nil)) + state.Register((*Filesystem)(nil)) + state.Register((*fileInodeOperations)(nil)) + state.Register((*Dir)(nil)) + state.Register((*Symlink)(nil)) + state.Register((*Socket)(nil)) + state.Register((*Fifo)(nil)) } diff --git a/pkg/sentry/fs/tty/tty_state_autogen.go b/pkg/sentry/fs/tty/tty_state_autogen.go index 25d601072..e82ca45a3 100644 --- a/pkg/sentry/fs/tty/tty_state_autogen.go +++ b/pkg/sentry/fs/tty/tty_state_autogen.go @@ -6,205 +6,376 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *dirInodeOperations) StateTypeName() string { + return "pkg/sentry/fs/tty.dirInodeOperations" +} + +func (x *dirInodeOperations) StateFields() []string { + return []string{ + "InodeSimpleAttributes", + "msrc", + "master", + "slaves", + "dentryMap", + "next", + } +} + func (x *dirInodeOperations) beforeSave() {} -func (x *dirInodeOperations) save(m state.Map) { + +func (x *dirInodeOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Save("msrc", &x.msrc) - m.Save("master", &x.master) - m.Save("slaves", &x.slaves) - m.Save("dentryMap", &x.dentryMap) - m.Save("next", &x.next) + m.Save(0, &x.InodeSimpleAttributes) + m.Save(1, &x.msrc) + m.Save(2, &x.master) + m.Save(3, &x.slaves) + m.Save(4, &x.dentryMap) + m.Save(5, &x.next) } func (x *dirInodeOperations) afterLoad() {} -func (x *dirInodeOperations) load(m state.Map) { - m.Load("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Load("msrc", &x.msrc) - m.Load("master", &x.master) - m.Load("slaves", &x.slaves) - m.Load("dentryMap", &x.dentryMap) - m.Load("next", &x.next) + +func (x *dirInodeOperations) StateLoad(m state.Source) { + m.Load(0, &x.InodeSimpleAttributes) + m.Load(1, &x.msrc) + m.Load(2, &x.master) + m.Load(3, &x.slaves) + m.Load(4, &x.dentryMap) + m.Load(5, &x.next) +} + +func (x *dirFileOperations) StateTypeName() string { + return "pkg/sentry/fs/tty.dirFileOperations" +} + +func (x *dirFileOperations) StateFields() []string { + return []string{ + "di", + "dirCursor", + } } func (x *dirFileOperations) beforeSave() {} -func (x *dirFileOperations) save(m state.Map) { + +func (x *dirFileOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("di", &x.di) - m.Save("dirCursor", &x.dirCursor) + m.Save(0, &x.di) + m.Save(1, &x.dirCursor) } func (x *dirFileOperations) afterLoad() {} -func (x *dirFileOperations) load(m state.Map) { - m.Load("di", &x.di) - m.Load("dirCursor", &x.dirCursor) + +func (x *dirFileOperations) StateLoad(m state.Source) { + m.Load(0, &x.di) + m.Load(1, &x.dirCursor) +} + +func (x *filesystem) StateTypeName() string { + return "pkg/sentry/fs/tty.filesystem" +} + +func (x *filesystem) StateFields() []string { + return []string{} } func (x *filesystem) beforeSave() {} -func (x *filesystem) save(m state.Map) { + +func (x *filesystem) StateSave(m state.Sink) { x.beforeSave() } func (x *filesystem) afterLoad() {} -func (x *filesystem) load(m state.Map) { + +func (x *filesystem) StateLoad(m state.Source) { +} + +func (x *superOperations) StateTypeName() string { + return "pkg/sentry/fs/tty.superOperations" +} + +func (x *superOperations) StateFields() []string { + return []string{} } func (x *superOperations) beforeSave() {} -func (x *superOperations) save(m state.Map) { + +func (x *superOperations) StateSave(m state.Sink) { x.beforeSave() } func (x *superOperations) afterLoad() {} -func (x *superOperations) load(m state.Map) { + +func (x *superOperations) StateLoad(m state.Source) { +} + +func (x *lineDiscipline) StateTypeName() string { + return "pkg/sentry/fs/tty.lineDiscipline" +} + +func (x *lineDiscipline) StateFields() []string { + return []string{ + "size", + "inQueue", + "outQueue", + "termios", + "column", + } } func (x *lineDiscipline) beforeSave() {} -func (x *lineDiscipline) save(m state.Map) { + +func (x *lineDiscipline) StateSave(m state.Sink) { x.beforeSave() if !state.IsZeroValue(&x.masterWaiter) { - m.Failf("masterWaiter is %#v, expected zero", &x.masterWaiter) + state.Failf("masterWaiter is %#v, expected zero", &x.masterWaiter) } if !state.IsZeroValue(&x.slaveWaiter) { - m.Failf("slaveWaiter is %#v, expected zero", &x.slaveWaiter) + state.Failf("slaveWaiter is %#v, expected zero", &x.slaveWaiter) } - m.Save("size", &x.size) - m.Save("inQueue", &x.inQueue) - m.Save("outQueue", &x.outQueue) - m.Save("termios", &x.termios) - m.Save("column", &x.column) + m.Save(0, &x.size) + m.Save(1, &x.inQueue) + m.Save(2, &x.outQueue) + m.Save(3, &x.termios) + m.Save(4, &x.column) } func (x *lineDiscipline) afterLoad() {} -func (x *lineDiscipline) load(m state.Map) { - m.Load("size", &x.size) - m.Load("inQueue", &x.inQueue) - m.Load("outQueue", &x.outQueue) - m.Load("termios", &x.termios) - m.Load("column", &x.column) + +func (x *lineDiscipline) StateLoad(m state.Source) { + m.Load(0, &x.size) + m.Load(1, &x.inQueue) + m.Load(2, &x.outQueue) + m.Load(3, &x.termios) + m.Load(4, &x.column) +} + +func (x *outputQueueTransformer) StateTypeName() string { + return "pkg/sentry/fs/tty.outputQueueTransformer" +} + +func (x *outputQueueTransformer) StateFields() []string { + return []string{} } func (x *outputQueueTransformer) beforeSave() {} -func (x *outputQueueTransformer) save(m state.Map) { + +func (x *outputQueueTransformer) StateSave(m state.Sink) { x.beforeSave() } func (x *outputQueueTransformer) afterLoad() {} -func (x *outputQueueTransformer) load(m state.Map) { + +func (x *outputQueueTransformer) StateLoad(m state.Source) { +} + +func (x *inputQueueTransformer) StateTypeName() string { + return "pkg/sentry/fs/tty.inputQueueTransformer" +} + +func (x *inputQueueTransformer) StateFields() []string { + return []string{} } func (x *inputQueueTransformer) beforeSave() {} -func (x *inputQueueTransformer) save(m state.Map) { + +func (x *inputQueueTransformer) StateSave(m state.Sink) { x.beforeSave() } func (x *inputQueueTransformer) afterLoad() {} -func (x *inputQueueTransformer) load(m state.Map) { + +func (x *inputQueueTransformer) StateLoad(m state.Source) { +} + +func (x *masterInodeOperations) StateTypeName() string { + return "pkg/sentry/fs/tty.masterInodeOperations" +} + +func (x *masterInodeOperations) StateFields() []string { + return []string{ + "SimpleFileInode", + "d", + } } func (x *masterInodeOperations) beforeSave() {} -func (x *masterInodeOperations) save(m state.Map) { + +func (x *masterInodeOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("SimpleFileInode", &x.SimpleFileInode) - m.Save("d", &x.d) + m.Save(0, &x.SimpleFileInode) + m.Save(1, &x.d) } func (x *masterInodeOperations) afterLoad() {} -func (x *masterInodeOperations) load(m state.Map) { - m.Load("SimpleFileInode", &x.SimpleFileInode) - m.Load("d", &x.d) + +func (x *masterInodeOperations) StateLoad(m state.Source) { + m.Load(0, &x.SimpleFileInode) + m.Load(1, &x.d) +} + +func (x *masterFileOperations) StateTypeName() string { + return "pkg/sentry/fs/tty.masterFileOperations" +} + +func (x *masterFileOperations) StateFields() []string { + return []string{ + "d", + "t", + } } func (x *masterFileOperations) beforeSave() {} -func (x *masterFileOperations) save(m state.Map) { + +func (x *masterFileOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("d", &x.d) - m.Save("t", &x.t) + m.Save(0, &x.d) + m.Save(1, &x.t) } func (x *masterFileOperations) afterLoad() {} -func (x *masterFileOperations) load(m state.Map) { - m.Load("d", &x.d) - m.Load("t", &x.t) + +func (x *masterFileOperations) StateLoad(m state.Source) { + m.Load(0, &x.d) + m.Load(1, &x.t) +} + +func (x *queue) StateTypeName() string { + return "pkg/sentry/fs/tty.queue" +} + +func (x *queue) StateFields() []string { + return []string{ + "readBuf", + "waitBuf", + "waitBufLen", + "readable", + "transformer", + } } func (x *queue) beforeSave() {} -func (x *queue) save(m state.Map) { + +func (x *queue) StateSave(m state.Sink) { x.beforeSave() - m.Save("readBuf", &x.readBuf) - m.Save("waitBuf", &x.waitBuf) - m.Save("waitBufLen", &x.waitBufLen) - m.Save("readable", &x.readable) - m.Save("transformer", &x.transformer) + m.Save(0, &x.readBuf) + m.Save(1, &x.waitBuf) + m.Save(2, &x.waitBufLen) + m.Save(3, &x.readable) + m.Save(4, &x.transformer) } func (x *queue) afterLoad() {} -func (x *queue) load(m state.Map) { - m.Load("readBuf", &x.readBuf) - m.Load("waitBuf", &x.waitBuf) - m.Load("waitBufLen", &x.waitBufLen) - m.Load("readable", &x.readable) - m.Load("transformer", &x.transformer) + +func (x *queue) StateLoad(m state.Source) { + m.Load(0, &x.readBuf) + m.Load(1, &x.waitBuf) + m.Load(2, &x.waitBufLen) + m.Load(3, &x.readable) + m.Load(4, &x.transformer) +} + +func (x *slaveInodeOperations) StateTypeName() string { + return "pkg/sentry/fs/tty.slaveInodeOperations" +} + +func (x *slaveInodeOperations) StateFields() []string { + return []string{ + "SimpleFileInode", + "d", + "t", + } } func (x *slaveInodeOperations) beforeSave() {} -func (x *slaveInodeOperations) save(m state.Map) { + +func (x *slaveInodeOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("SimpleFileInode", &x.SimpleFileInode) - m.Save("d", &x.d) - m.Save("t", &x.t) + m.Save(0, &x.SimpleFileInode) + m.Save(1, &x.d) + m.Save(2, &x.t) } func (x *slaveInodeOperations) afterLoad() {} -func (x *slaveInodeOperations) load(m state.Map) { - m.Load("SimpleFileInode", &x.SimpleFileInode) - m.Load("d", &x.d) - m.Load("t", &x.t) + +func (x *slaveInodeOperations) StateLoad(m state.Source) { + m.Load(0, &x.SimpleFileInode) + m.Load(1, &x.d) + m.Load(2, &x.t) +} + +func (x *slaveFileOperations) StateTypeName() string { + return "pkg/sentry/fs/tty.slaveFileOperations" +} + +func (x *slaveFileOperations) StateFields() []string { + return []string{ + "si", + } } func (x *slaveFileOperations) beforeSave() {} -func (x *slaveFileOperations) save(m state.Map) { + +func (x *slaveFileOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("si", &x.si) + m.Save(0, &x.si) } func (x *slaveFileOperations) afterLoad() {} -func (x *slaveFileOperations) load(m state.Map) { - m.Load("si", &x.si) + +func (x *slaveFileOperations) StateLoad(m state.Source) { + m.Load(0, &x.si) +} + +func (x *Terminal) StateTypeName() string { + return "pkg/sentry/fs/tty.Terminal" +} + +func (x *Terminal) StateFields() []string { + return []string{ + "AtomicRefCount", + "n", + "d", + "ld", + "masterKTTY", + "slaveKTTY", + } } func (x *Terminal) beforeSave() {} -func (x *Terminal) save(m state.Map) { + +func (x *Terminal) StateSave(m state.Sink) { x.beforeSave() - m.Save("AtomicRefCount", &x.AtomicRefCount) - m.Save("n", &x.n) - m.Save("d", &x.d) - m.Save("ld", &x.ld) - m.Save("masterKTTY", &x.masterKTTY) - m.Save("slaveKTTY", &x.slaveKTTY) + m.Save(0, &x.AtomicRefCount) + m.Save(1, &x.n) + m.Save(2, &x.d) + m.Save(3, &x.ld) + m.Save(4, &x.masterKTTY) + m.Save(5, &x.slaveKTTY) } func (x *Terminal) afterLoad() {} -func (x *Terminal) load(m state.Map) { - m.Load("AtomicRefCount", &x.AtomicRefCount) - m.Load("n", &x.n) - m.Load("d", &x.d) - m.Load("ld", &x.ld) - m.Load("masterKTTY", &x.masterKTTY) - m.Load("slaveKTTY", &x.slaveKTTY) + +func (x *Terminal) StateLoad(m state.Source) { + m.Load(0, &x.AtomicRefCount) + m.Load(1, &x.n) + m.Load(2, &x.d) + m.Load(3, &x.ld) + m.Load(4, &x.masterKTTY) + m.Load(5, &x.slaveKTTY) } func init() { - state.Register("pkg/sentry/fs/tty.dirInodeOperations", (*dirInodeOperations)(nil), state.Fns{Save: (*dirInodeOperations).save, Load: (*dirInodeOperations).load}) - state.Register("pkg/sentry/fs/tty.dirFileOperations", (*dirFileOperations)(nil), state.Fns{Save: (*dirFileOperations).save, Load: (*dirFileOperations).load}) - state.Register("pkg/sentry/fs/tty.filesystem", (*filesystem)(nil), state.Fns{Save: (*filesystem).save, Load: (*filesystem).load}) - state.Register("pkg/sentry/fs/tty.superOperations", (*superOperations)(nil), state.Fns{Save: (*superOperations).save, Load: (*superOperations).load}) - state.Register("pkg/sentry/fs/tty.lineDiscipline", (*lineDiscipline)(nil), state.Fns{Save: (*lineDiscipline).save, Load: (*lineDiscipline).load}) - state.Register("pkg/sentry/fs/tty.outputQueueTransformer", (*outputQueueTransformer)(nil), state.Fns{Save: (*outputQueueTransformer).save, Load: (*outputQueueTransformer).load}) - state.Register("pkg/sentry/fs/tty.inputQueueTransformer", (*inputQueueTransformer)(nil), state.Fns{Save: (*inputQueueTransformer).save, Load: (*inputQueueTransformer).load}) - state.Register("pkg/sentry/fs/tty.masterInodeOperations", (*masterInodeOperations)(nil), state.Fns{Save: (*masterInodeOperations).save, Load: (*masterInodeOperations).load}) - state.Register("pkg/sentry/fs/tty.masterFileOperations", (*masterFileOperations)(nil), state.Fns{Save: (*masterFileOperations).save, Load: (*masterFileOperations).load}) - state.Register("pkg/sentry/fs/tty.queue", (*queue)(nil), state.Fns{Save: (*queue).save, Load: (*queue).load}) - state.Register("pkg/sentry/fs/tty.slaveInodeOperations", (*slaveInodeOperations)(nil), state.Fns{Save: (*slaveInodeOperations).save, Load: (*slaveInodeOperations).load}) - state.Register("pkg/sentry/fs/tty.slaveFileOperations", (*slaveFileOperations)(nil), state.Fns{Save: (*slaveFileOperations).save, Load: (*slaveFileOperations).load}) - state.Register("pkg/sentry/fs/tty.Terminal", (*Terminal)(nil), state.Fns{Save: (*Terminal).save, Load: (*Terminal).load}) + state.Register((*dirInodeOperations)(nil)) + state.Register((*dirFileOperations)(nil)) + state.Register((*filesystem)(nil)) + state.Register((*superOperations)(nil)) + state.Register((*lineDiscipline)(nil)) + state.Register((*outputQueueTransformer)(nil)) + state.Register((*inputQueueTransformer)(nil)) + state.Register((*masterInodeOperations)(nil)) + state.Register((*masterFileOperations)(nil)) + state.Register((*queue)(nil)) + state.Register((*slaveInodeOperations)(nil)) + state.Register((*slaveFileOperations)(nil)) + state.Register((*Terminal)(nil)) } diff --git a/pkg/sentry/fsbridge/fsbridge_state_autogen.go b/pkg/sentry/fsbridge/fsbridge_state_autogen.go index d370b2d47..d69b50c28 100644 --- a/pkg/sentry/fsbridge/fsbridge_state_autogen.go +++ b/pkg/sentry/fsbridge/fsbridge_state_autogen.go @@ -6,61 +6,113 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *fsFile) StateTypeName() string { + return "pkg/sentry/fsbridge.fsFile" +} + +func (x *fsFile) StateFields() []string { + return []string{ + "file", + } +} + func (x *fsFile) beforeSave() {} -func (x *fsFile) save(m state.Map) { + +func (x *fsFile) StateSave(m state.Sink) { x.beforeSave() - m.Save("file", &x.file) + m.Save(0, &x.file) } func (x *fsFile) afterLoad() {} -func (x *fsFile) load(m state.Map) { - m.Load("file", &x.file) + +func (x *fsFile) StateLoad(m state.Source) { + m.Load(0, &x.file) +} + +func (x *fsLookup) StateTypeName() string { + return "pkg/sentry/fsbridge.fsLookup" +} + +func (x *fsLookup) StateFields() []string { + return []string{ + "mntns", + "root", + "workingDir", + } } func (x *fsLookup) beforeSave() {} -func (x *fsLookup) save(m state.Map) { + +func (x *fsLookup) StateSave(m state.Sink) { x.beforeSave() - m.Save("mntns", &x.mntns) - m.Save("root", &x.root) - m.Save("workingDir", &x.workingDir) + m.Save(0, &x.mntns) + m.Save(1, &x.root) + m.Save(2, &x.workingDir) } func (x *fsLookup) afterLoad() {} -func (x *fsLookup) load(m state.Map) { - m.Load("mntns", &x.mntns) - m.Load("root", &x.root) - m.Load("workingDir", &x.workingDir) + +func (x *fsLookup) StateLoad(m state.Source) { + m.Load(0, &x.mntns) + m.Load(1, &x.root) + m.Load(2, &x.workingDir) +} + +func (x *VFSFile) StateTypeName() string { + return "pkg/sentry/fsbridge.VFSFile" +} + +func (x *VFSFile) StateFields() []string { + return []string{ + "file", + } } func (x *VFSFile) beforeSave() {} -func (x *VFSFile) save(m state.Map) { + +func (x *VFSFile) StateSave(m state.Sink) { x.beforeSave() - m.Save("file", &x.file) + m.Save(0, &x.file) } func (x *VFSFile) afterLoad() {} -func (x *VFSFile) load(m state.Map) { - m.Load("file", &x.file) + +func (x *VFSFile) StateLoad(m state.Source) { + m.Load(0, &x.file) +} + +func (x *vfsLookup) StateTypeName() string { + return "pkg/sentry/fsbridge.vfsLookup" +} + +func (x *vfsLookup) StateFields() []string { + return []string{ + "mntns", + "root", + "workingDir", + } } func (x *vfsLookup) beforeSave() {} -func (x *vfsLookup) save(m state.Map) { + +func (x *vfsLookup) StateSave(m state.Sink) { x.beforeSave() - m.Save("mntns", &x.mntns) - m.Save("root", &x.root) - m.Save("workingDir", &x.workingDir) + m.Save(0, &x.mntns) + m.Save(1, &x.root) + m.Save(2, &x.workingDir) } func (x *vfsLookup) afterLoad() {} -func (x *vfsLookup) load(m state.Map) { - m.Load("mntns", &x.mntns) - m.Load("root", &x.root) - m.Load("workingDir", &x.workingDir) + +func (x *vfsLookup) StateLoad(m state.Source) { + m.Load(0, &x.mntns) + m.Load(1, &x.root) + m.Load(2, &x.workingDir) } func init() { - state.Register("pkg/sentry/fsbridge.fsFile", (*fsFile)(nil), state.Fns{Save: (*fsFile).save, Load: (*fsFile).load}) - state.Register("pkg/sentry/fsbridge.fsLookup", (*fsLookup)(nil), state.Fns{Save: (*fsLookup).save, Load: (*fsLookup).load}) - state.Register("pkg/sentry/fsbridge.VFSFile", (*VFSFile)(nil), state.Fns{Save: (*VFSFile).save, Load: (*VFSFile).load}) - state.Register("pkg/sentry/fsbridge.vfsLookup", (*vfsLookup)(nil), state.Fns{Save: (*vfsLookup).save, Load: (*vfsLookup).load}) + state.Register((*fsFile)(nil)) + state.Register((*fsLookup)(nil)) + state.Register((*VFSFile)(nil)) + state.Register((*vfsLookup)(nil)) } diff --git a/pkg/sentry/fsimpl/devpts/devpts_state_autogen.go b/pkg/sentry/fsimpl/devpts/devpts_state_autogen.go index 90cd7937c..5942f7bac 100644 --- a/pkg/sentry/fsimpl/devpts/devpts_state_autogen.go +++ b/pkg/sentry/fsimpl/devpts/devpts_state_autogen.go @@ -6,89 +6,156 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *lineDiscipline) StateTypeName() string { + return "pkg/sentry/fsimpl/devpts.lineDiscipline" +} + +func (x *lineDiscipline) StateFields() []string { + return []string{ + "size", + "inQueue", + "outQueue", + "termios", + "column", + } +} + func (x *lineDiscipline) beforeSave() {} -func (x *lineDiscipline) save(m state.Map) { + +func (x *lineDiscipline) StateSave(m state.Sink) { x.beforeSave() if !state.IsZeroValue(&x.masterWaiter) { - m.Failf("masterWaiter is %#v, expected zero", &x.masterWaiter) + state.Failf("masterWaiter is %#v, expected zero", &x.masterWaiter) } if !state.IsZeroValue(&x.slaveWaiter) { - m.Failf("slaveWaiter is %#v, expected zero", &x.slaveWaiter) + state.Failf("slaveWaiter is %#v, expected zero", &x.slaveWaiter) } - m.Save("size", &x.size) - m.Save("inQueue", &x.inQueue) - m.Save("outQueue", &x.outQueue) - m.Save("termios", &x.termios) - m.Save("column", &x.column) + m.Save(0, &x.size) + m.Save(1, &x.inQueue) + m.Save(2, &x.outQueue) + m.Save(3, &x.termios) + m.Save(4, &x.column) } func (x *lineDiscipline) afterLoad() {} -func (x *lineDiscipline) load(m state.Map) { - m.Load("size", &x.size) - m.Load("inQueue", &x.inQueue) - m.Load("outQueue", &x.outQueue) - m.Load("termios", &x.termios) - m.Load("column", &x.column) + +func (x *lineDiscipline) StateLoad(m state.Source) { + m.Load(0, &x.size) + m.Load(1, &x.inQueue) + m.Load(2, &x.outQueue) + m.Load(3, &x.termios) + m.Load(4, &x.column) +} + +func (x *outputQueueTransformer) StateTypeName() string { + return "pkg/sentry/fsimpl/devpts.outputQueueTransformer" +} + +func (x *outputQueueTransformer) StateFields() []string { + return []string{} } func (x *outputQueueTransformer) beforeSave() {} -func (x *outputQueueTransformer) save(m state.Map) { + +func (x *outputQueueTransformer) StateSave(m state.Sink) { x.beforeSave() } func (x *outputQueueTransformer) afterLoad() {} -func (x *outputQueueTransformer) load(m state.Map) { + +func (x *outputQueueTransformer) StateLoad(m state.Source) { +} + +func (x *inputQueueTransformer) StateTypeName() string { + return "pkg/sentry/fsimpl/devpts.inputQueueTransformer" +} + +func (x *inputQueueTransformer) StateFields() []string { + return []string{} } func (x *inputQueueTransformer) beforeSave() {} -func (x *inputQueueTransformer) save(m state.Map) { + +func (x *inputQueueTransformer) StateSave(m state.Sink) { x.beforeSave() } func (x *inputQueueTransformer) afterLoad() {} -func (x *inputQueueTransformer) load(m state.Map) { + +func (x *inputQueueTransformer) StateLoad(m state.Source) { +} + +func (x *queue) StateTypeName() string { + return "pkg/sentry/fsimpl/devpts.queue" +} + +func (x *queue) StateFields() []string { + return []string{ + "readBuf", + "waitBuf", + "waitBufLen", + "readable", + "transformer", + } } func (x *queue) beforeSave() {} -func (x *queue) save(m state.Map) { + +func (x *queue) StateSave(m state.Sink) { x.beforeSave() - m.Save("readBuf", &x.readBuf) - m.Save("waitBuf", &x.waitBuf) - m.Save("waitBufLen", &x.waitBufLen) - m.Save("readable", &x.readable) - m.Save("transformer", &x.transformer) + m.Save(0, &x.readBuf) + m.Save(1, &x.waitBuf) + m.Save(2, &x.waitBufLen) + m.Save(3, &x.readable) + m.Save(4, &x.transformer) } func (x *queue) afterLoad() {} -func (x *queue) load(m state.Map) { - m.Load("readBuf", &x.readBuf) - m.Load("waitBuf", &x.waitBuf) - m.Load("waitBufLen", &x.waitBufLen) - m.Load("readable", &x.readable) - m.Load("transformer", &x.transformer) + +func (x *queue) StateLoad(m state.Source) { + m.Load(0, &x.readBuf) + m.Load(1, &x.waitBuf) + m.Load(2, &x.waitBufLen) + m.Load(3, &x.readable) + m.Load(4, &x.transformer) +} + +func (x *Terminal) StateTypeName() string { + return "pkg/sentry/fsimpl/devpts.Terminal" +} + +func (x *Terminal) StateFields() []string { + return []string{ + "n", + "ld", + "masterKTTY", + "slaveKTTY", + } } func (x *Terminal) beforeSave() {} -func (x *Terminal) save(m state.Map) { + +func (x *Terminal) StateSave(m state.Sink) { x.beforeSave() - m.Save("n", &x.n) - m.Save("ld", &x.ld) - m.Save("masterKTTY", &x.masterKTTY) - m.Save("slaveKTTY", &x.slaveKTTY) + m.Save(0, &x.n) + m.Save(1, &x.ld) + m.Save(2, &x.masterKTTY) + m.Save(3, &x.slaveKTTY) } func (x *Terminal) afterLoad() {} -func (x *Terminal) load(m state.Map) { - m.Load("n", &x.n) - m.Load("ld", &x.ld) - m.Load("masterKTTY", &x.masterKTTY) - m.Load("slaveKTTY", &x.slaveKTTY) + +func (x *Terminal) StateLoad(m state.Source) { + m.Load(0, &x.n) + m.Load(1, &x.ld) + m.Load(2, &x.masterKTTY) + m.Load(3, &x.slaveKTTY) } func init() { - state.Register("pkg/sentry/fsimpl/devpts.lineDiscipline", (*lineDiscipline)(nil), state.Fns{Save: (*lineDiscipline).save, Load: (*lineDiscipline).load}) - state.Register("pkg/sentry/fsimpl/devpts.outputQueueTransformer", (*outputQueueTransformer)(nil), state.Fns{Save: (*outputQueueTransformer).save, Load: (*outputQueueTransformer).load}) - state.Register("pkg/sentry/fsimpl/devpts.inputQueueTransformer", (*inputQueueTransformer)(nil), state.Fns{Save: (*inputQueueTransformer).save, Load: (*inputQueueTransformer).load}) - state.Register("pkg/sentry/fsimpl/devpts.queue", (*queue)(nil), state.Fns{Save: (*queue).save, Load: (*queue).load}) - state.Register("pkg/sentry/fsimpl/devpts.Terminal", (*Terminal)(nil), state.Fns{Save: (*Terminal).save, Load: (*Terminal).load}) + state.Register((*lineDiscipline)(nil)) + state.Register((*outputQueueTransformer)(nil)) + state.Register((*inputQueueTransformer)(nil)) + state.Register((*queue)(nil)) + state.Register((*Terminal)(nil)) } diff --git a/pkg/sentry/fsimpl/gofer/dentry_list.go b/pkg/sentry/fsimpl/gofer/dentry_list.go index fa03e2501..84f839e3a 100644 --- a/pkg/sentry/fsimpl/gofer/dentry_list.go +++ b/pkg/sentry/fsimpl/gofer/dentry_list.go @@ -56,7 +56,7 @@ func (l *dentryList) Back() *dentry { // // NOTE: This is an O(n) operation. func (l *dentryList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (dentryElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *dentryList) Remove(e *dentry) { if prev != nil { dentryElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { dentryElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/fsimpl/gofer/gofer_state_autogen.go b/pkg/sentry/fsimpl/gofer/gofer_state_autogen.go index 546d432c9..19b1eef9e 100644 --- a/pkg/sentry/fsimpl/gofer/gofer_state_autogen.go +++ b/pkg/sentry/fsimpl/gofer/gofer_state_autogen.go @@ -6,33 +6,59 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *dentryList) StateTypeName() string { + return "pkg/sentry/fsimpl/gofer.dentryList" +} + +func (x *dentryList) StateFields() []string { + return []string{ + "head", + "tail", + } +} + func (x *dentryList) beforeSave() {} -func (x *dentryList) save(m state.Map) { + +func (x *dentryList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *dentryList) afterLoad() {} -func (x *dentryList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *dentryList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *dentryEntry) StateTypeName() string { + return "pkg/sentry/fsimpl/gofer.dentryEntry" +} + +func (x *dentryEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *dentryEntry) beforeSave() {} -func (x *dentryEntry) save(m state.Map) { + +func (x *dentryEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *dentryEntry) afterLoad() {} -func (x *dentryEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *dentryEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) } func init() { - state.Register("pkg/sentry/fsimpl/gofer.dentryList", (*dentryList)(nil), state.Fns{Save: (*dentryList).save, Load: (*dentryList).load}) - state.Register("pkg/sentry/fsimpl/gofer.dentryEntry", (*dentryEntry)(nil), state.Fns{Save: (*dentryEntry).save, Load: (*dentryEntry).load}) + state.Register((*dentryList)(nil)) + state.Register((*dentryEntry)(nil)) } diff --git a/pkg/sentry/fsimpl/host/host_state_autogen.go b/pkg/sentry/fsimpl/host/host_state_autogen.go index 28bc79d04..17320c417 100644 --- a/pkg/sentry/fsimpl/host/host_state_autogen.go +++ b/pkg/sentry/fsimpl/host/host_state_autogen.go @@ -6,23 +6,38 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *ConnectedEndpoint) StateTypeName() string { + return "pkg/sentry/fsimpl/host.ConnectedEndpoint" +} + +func (x *ConnectedEndpoint) StateFields() []string { + return []string{ + "ref", + "fd", + "addr", + "stype", + } +} + func (x *ConnectedEndpoint) beforeSave() {} -func (x *ConnectedEndpoint) save(m state.Map) { + +func (x *ConnectedEndpoint) StateSave(m state.Sink) { x.beforeSave() - m.Save("ref", &x.ref) - m.Save("fd", &x.fd) - m.Save("addr", &x.addr) - m.Save("stype", &x.stype) + m.Save(0, &x.ref) + m.Save(1, &x.fd) + m.Save(2, &x.addr) + m.Save(3, &x.stype) } func (x *ConnectedEndpoint) afterLoad() {} -func (x *ConnectedEndpoint) load(m state.Map) { - m.Load("ref", &x.ref) - m.Load("fd", &x.fd) - m.Load("addr", &x.addr) - m.Load("stype", &x.stype) + +func (x *ConnectedEndpoint) StateLoad(m state.Source) { + m.Load(0, &x.ref) + m.Load(1, &x.fd) + m.Load(2, &x.addr) + m.Load(3, &x.stype) } func init() { - state.Register("pkg/sentry/fsimpl/host.ConnectedEndpoint", (*ConnectedEndpoint)(nil), state.Fns{Save: (*ConnectedEndpoint).save, Load: (*ConnectedEndpoint).load}) + state.Register((*ConnectedEndpoint)(nil)) } diff --git a/pkg/sentry/fsimpl/kernfs/kernfs_state_autogen.go b/pkg/sentry/fsimpl/kernfs/kernfs_state_autogen.go index 61b2c460f..371b1481c 100644 --- a/pkg/sentry/fsimpl/kernfs/kernfs_state_autogen.go +++ b/pkg/sentry/fsimpl/kernfs/kernfs_state_autogen.go @@ -6,97 +6,173 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *DynamicBytesFile) StateTypeName() string { + return "pkg/sentry/fsimpl/kernfs.DynamicBytesFile" +} + +func (x *DynamicBytesFile) StateFields() []string { + return []string{ + "InodeAttrs", + "InodeNoopRefCount", + "InodeNotDirectory", + "InodeNotSymlink", + "locks", + "data", + } +} + func (x *DynamicBytesFile) beforeSave() {} -func (x *DynamicBytesFile) save(m state.Map) { + +func (x *DynamicBytesFile) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeAttrs", &x.InodeAttrs) - m.Save("InodeNoopRefCount", &x.InodeNoopRefCount) - m.Save("InodeNotDirectory", &x.InodeNotDirectory) - m.Save("InodeNotSymlink", &x.InodeNotSymlink) - m.Save("locks", &x.locks) - m.Save("data", &x.data) + m.Save(0, &x.InodeAttrs) + m.Save(1, &x.InodeNoopRefCount) + m.Save(2, &x.InodeNotDirectory) + m.Save(3, &x.InodeNotSymlink) + m.Save(4, &x.locks) + m.Save(5, &x.data) } func (x *DynamicBytesFile) afterLoad() {} -func (x *DynamicBytesFile) load(m state.Map) { - m.Load("InodeAttrs", &x.InodeAttrs) - m.Load("InodeNoopRefCount", &x.InodeNoopRefCount) - m.Load("InodeNotDirectory", &x.InodeNotDirectory) - m.Load("InodeNotSymlink", &x.InodeNotSymlink) - m.Load("locks", &x.locks) - m.Load("data", &x.data) + +func (x *DynamicBytesFile) StateLoad(m state.Source) { + m.Load(0, &x.InodeAttrs) + m.Load(1, &x.InodeNoopRefCount) + m.Load(2, &x.InodeNotDirectory) + m.Load(3, &x.InodeNotSymlink) + m.Load(4, &x.locks) + m.Load(5, &x.data) +} + +func (x *DynamicBytesFD) StateTypeName() string { + return "pkg/sentry/fsimpl/kernfs.DynamicBytesFD" +} + +func (x *DynamicBytesFD) StateFields() []string { + return []string{ + "FileDescriptionDefaultImpl", + "DynamicBytesFileDescriptionImpl", + "LockFD", + "vfsfd", + "inode", + } } func (x *DynamicBytesFD) beforeSave() {} -func (x *DynamicBytesFD) save(m state.Map) { + +func (x *DynamicBytesFD) StateSave(m state.Sink) { x.beforeSave() - m.Save("FileDescriptionDefaultImpl", &x.FileDescriptionDefaultImpl) - m.Save("DynamicBytesFileDescriptionImpl", &x.DynamicBytesFileDescriptionImpl) - m.Save("LockFD", &x.LockFD) - m.Save("vfsfd", &x.vfsfd) - m.Save("inode", &x.inode) + m.Save(0, &x.FileDescriptionDefaultImpl) + m.Save(1, &x.DynamicBytesFileDescriptionImpl) + m.Save(2, &x.LockFD) + m.Save(3, &x.vfsfd) + m.Save(4, &x.inode) } func (x *DynamicBytesFD) afterLoad() {} -func (x *DynamicBytesFD) load(m state.Map) { - m.Load("FileDescriptionDefaultImpl", &x.FileDescriptionDefaultImpl) - m.Load("DynamicBytesFileDescriptionImpl", &x.DynamicBytesFileDescriptionImpl) - m.Load("LockFD", &x.LockFD) - m.Load("vfsfd", &x.vfsfd) - m.Load("inode", &x.inode) + +func (x *DynamicBytesFD) StateLoad(m state.Source) { + m.Load(0, &x.FileDescriptionDefaultImpl) + m.Load(1, &x.DynamicBytesFileDescriptionImpl) + m.Load(2, &x.LockFD) + m.Load(3, &x.vfsfd) + m.Load(4, &x.inode) +} + +func (x *StaticDirectory) StateTypeName() string { + return "pkg/sentry/fsimpl/kernfs.StaticDirectory" +} + +func (x *StaticDirectory) StateFields() []string { + return []string{ + "InodeNotSymlink", + "InodeDirectoryNoNewChildren", + "InodeAttrs", + "InodeNoDynamicLookup", + "OrderedChildren", + "locks", + } } func (x *StaticDirectory) beforeSave() {} -func (x *StaticDirectory) save(m state.Map) { + +func (x *StaticDirectory) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeNotSymlink", &x.InodeNotSymlink) - m.Save("InodeDirectoryNoNewChildren", &x.InodeDirectoryNoNewChildren) - m.Save("InodeAttrs", &x.InodeAttrs) - m.Save("InodeNoDynamicLookup", &x.InodeNoDynamicLookup) - m.Save("OrderedChildren", &x.OrderedChildren) - m.Save("locks", &x.locks) + m.Save(0, &x.InodeNotSymlink) + m.Save(1, &x.InodeDirectoryNoNewChildren) + m.Save(2, &x.InodeAttrs) + m.Save(3, &x.InodeNoDynamicLookup) + m.Save(4, &x.OrderedChildren) + m.Save(5, &x.locks) } func (x *StaticDirectory) afterLoad() {} -func (x *StaticDirectory) load(m state.Map) { - m.Load("InodeNotSymlink", &x.InodeNotSymlink) - m.Load("InodeDirectoryNoNewChildren", &x.InodeDirectoryNoNewChildren) - m.Load("InodeAttrs", &x.InodeAttrs) - m.Load("InodeNoDynamicLookup", &x.InodeNoDynamicLookup) - m.Load("OrderedChildren", &x.OrderedChildren) - m.Load("locks", &x.locks) + +func (x *StaticDirectory) StateLoad(m state.Source) { + m.Load(0, &x.InodeNotSymlink) + m.Load(1, &x.InodeDirectoryNoNewChildren) + m.Load(2, &x.InodeAttrs) + m.Load(3, &x.InodeNoDynamicLookup) + m.Load(4, &x.OrderedChildren) + m.Load(5, &x.locks) +} + +func (x *slotList) StateTypeName() string { + return "pkg/sentry/fsimpl/kernfs.slotList" +} + +func (x *slotList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *slotList) beforeSave() {} -func (x *slotList) save(m state.Map) { + +func (x *slotList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *slotList) afterLoad() {} -func (x *slotList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *slotList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *slotEntry) StateTypeName() string { + return "pkg/sentry/fsimpl/kernfs.slotEntry" +} + +func (x *slotEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *slotEntry) beforeSave() {} -func (x *slotEntry) save(m state.Map) { + +func (x *slotEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *slotEntry) afterLoad() {} -func (x *slotEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *slotEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) } func init() { - state.Register("pkg/sentry/fsimpl/kernfs.DynamicBytesFile", (*DynamicBytesFile)(nil), state.Fns{Save: (*DynamicBytesFile).save, Load: (*DynamicBytesFile).load}) - state.Register("pkg/sentry/fsimpl/kernfs.DynamicBytesFD", (*DynamicBytesFD)(nil), state.Fns{Save: (*DynamicBytesFD).save, Load: (*DynamicBytesFD).load}) - state.Register("pkg/sentry/fsimpl/kernfs.StaticDirectory", (*StaticDirectory)(nil), state.Fns{Save: (*StaticDirectory).save, Load: (*StaticDirectory).load}) - state.Register("pkg/sentry/fsimpl/kernfs.slotList", (*slotList)(nil), state.Fns{Save: (*slotList).save, Load: (*slotList).load}) - state.Register("pkg/sentry/fsimpl/kernfs.slotEntry", (*slotEntry)(nil), state.Fns{Save: (*slotEntry).save, Load: (*slotEntry).load}) + state.Register((*DynamicBytesFile)(nil)) + state.Register((*DynamicBytesFD)(nil)) + state.Register((*StaticDirectory)(nil)) + state.Register((*slotList)(nil)) + state.Register((*slotEntry)(nil)) } diff --git a/pkg/sentry/fsimpl/kernfs/slot_list.go b/pkg/sentry/fsimpl/kernfs/slot_list.go index 09c30bca7..c6cd74660 100644 --- a/pkg/sentry/fsimpl/kernfs/slot_list.go +++ b/pkg/sentry/fsimpl/kernfs/slot_list.go @@ -56,7 +56,7 @@ func (l *slotList) Back() *slot { // // NOTE: This is an O(n) operation. func (l *slotList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (slotElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *slotList) Remove(e *slot) { if prev != nil { slotElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { slotElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/fsimpl/proc/proc_state_autogen.go b/pkg/sentry/fsimpl/proc/proc_state_autogen.go index b940c9973..e297a6257 100644 --- a/pkg/sentry/fsimpl/proc/proc_state_autogen.go +++ b/pkg/sentry/fsimpl/proc/proc_state_autogen.go @@ -6,647 +6,1213 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *FilesystemType) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.FilesystemType" +} + +func (x *FilesystemType) StateFields() []string { + return []string{} +} + func (x *FilesystemType) beforeSave() {} -func (x *FilesystemType) save(m state.Map) { + +func (x *FilesystemType) StateSave(m state.Sink) { x.beforeSave() } func (x *FilesystemType) afterLoad() {} -func (x *FilesystemType) load(m state.Map) { + +func (x *FilesystemType) StateLoad(m state.Source) { +} + +func (x *subtasksInode) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.subtasksInode" +} + +func (x *subtasksInode) StateFields() []string { + return []string{ + "InodeNotSymlink", + "InodeDirectoryNoNewChildren", + "InodeAttrs", + "OrderedChildren", + "AlwaysValid", + "locks", + "fs", + "task", + "pidns", + "cgroupControllers", + } } func (x *subtasksInode) beforeSave() {} -func (x *subtasksInode) save(m state.Map) { + +func (x *subtasksInode) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeNotSymlink", &x.InodeNotSymlink) - m.Save("InodeDirectoryNoNewChildren", &x.InodeDirectoryNoNewChildren) - m.Save("InodeAttrs", &x.InodeAttrs) - m.Save("OrderedChildren", &x.OrderedChildren) - m.Save("AlwaysValid", &x.AlwaysValid) - m.Save("locks", &x.locks) - m.Save("fs", &x.fs) - m.Save("task", &x.task) - m.Save("pidns", &x.pidns) - m.Save("cgroupControllers", &x.cgroupControllers) + m.Save(0, &x.InodeNotSymlink) + m.Save(1, &x.InodeDirectoryNoNewChildren) + m.Save(2, &x.InodeAttrs) + m.Save(3, &x.OrderedChildren) + m.Save(4, &x.AlwaysValid) + m.Save(5, &x.locks) + m.Save(6, &x.fs) + m.Save(7, &x.task) + m.Save(8, &x.pidns) + m.Save(9, &x.cgroupControllers) } func (x *subtasksInode) afterLoad() {} -func (x *subtasksInode) load(m state.Map) { - m.Load("InodeNotSymlink", &x.InodeNotSymlink) - m.Load("InodeDirectoryNoNewChildren", &x.InodeDirectoryNoNewChildren) - m.Load("InodeAttrs", &x.InodeAttrs) - m.Load("OrderedChildren", &x.OrderedChildren) - m.Load("AlwaysValid", &x.AlwaysValid) - m.Load("locks", &x.locks) - m.Load("fs", &x.fs) - m.Load("task", &x.task) - m.Load("pidns", &x.pidns) - m.Load("cgroupControllers", &x.cgroupControllers) + +func (x *subtasksInode) StateLoad(m state.Source) { + m.Load(0, &x.InodeNotSymlink) + m.Load(1, &x.InodeDirectoryNoNewChildren) + m.Load(2, &x.InodeAttrs) + m.Load(3, &x.OrderedChildren) + m.Load(4, &x.AlwaysValid) + m.Load(5, &x.locks) + m.Load(6, &x.fs) + m.Load(7, &x.task) + m.Load(8, &x.pidns) + m.Load(9, &x.cgroupControllers) +} + +func (x *taskInode) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.taskInode" +} + +func (x *taskInode) StateFields() []string { + return []string{ + "InodeNotSymlink", + "InodeDirectoryNoNewChildren", + "InodeNoDynamicLookup", + "InodeAttrs", + "OrderedChildren", + "locks", + "task", + } } func (x *taskInode) beforeSave() {} -func (x *taskInode) save(m state.Map) { + +func (x *taskInode) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeNotSymlink", &x.InodeNotSymlink) - m.Save("InodeDirectoryNoNewChildren", &x.InodeDirectoryNoNewChildren) - m.Save("InodeNoDynamicLookup", &x.InodeNoDynamicLookup) - m.Save("InodeAttrs", &x.InodeAttrs) - m.Save("OrderedChildren", &x.OrderedChildren) - m.Save("locks", &x.locks) - m.Save("task", &x.task) + m.Save(0, &x.InodeNotSymlink) + m.Save(1, &x.InodeDirectoryNoNewChildren) + m.Save(2, &x.InodeNoDynamicLookup) + m.Save(3, &x.InodeAttrs) + m.Save(4, &x.OrderedChildren) + m.Save(5, &x.locks) + m.Save(6, &x.task) } func (x *taskInode) afterLoad() {} -func (x *taskInode) load(m state.Map) { - m.Load("InodeNotSymlink", &x.InodeNotSymlink) - m.Load("InodeDirectoryNoNewChildren", &x.InodeDirectoryNoNewChildren) - m.Load("InodeNoDynamicLookup", &x.InodeNoDynamicLookup) - m.Load("InodeAttrs", &x.InodeAttrs) - m.Load("OrderedChildren", &x.OrderedChildren) - m.Load("locks", &x.locks) - m.Load("task", &x.task) + +func (x *taskInode) StateLoad(m state.Source) { + m.Load(0, &x.InodeNotSymlink) + m.Load(1, &x.InodeDirectoryNoNewChildren) + m.Load(2, &x.InodeNoDynamicLookup) + m.Load(3, &x.InodeAttrs) + m.Load(4, &x.OrderedChildren) + m.Load(5, &x.locks) + m.Load(6, &x.task) +} + +func (x *fdDirInode) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.fdDirInode" +} + +func (x *fdDirInode) StateFields() []string { + return []string{ + "InodeNotSymlink", + "InodeDirectoryNoNewChildren", + "InodeAttrs", + "OrderedChildren", + "AlwaysValid", + "fdDir", + } } func (x *fdDirInode) beforeSave() {} -func (x *fdDirInode) save(m state.Map) { + +func (x *fdDirInode) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeNotSymlink", &x.InodeNotSymlink) - m.Save("InodeDirectoryNoNewChildren", &x.InodeDirectoryNoNewChildren) - m.Save("InodeAttrs", &x.InodeAttrs) - m.Save("OrderedChildren", &x.OrderedChildren) - m.Save("AlwaysValid", &x.AlwaysValid) - m.Save("fdDir", &x.fdDir) + m.Save(0, &x.InodeNotSymlink) + m.Save(1, &x.InodeDirectoryNoNewChildren) + m.Save(2, &x.InodeAttrs) + m.Save(3, &x.OrderedChildren) + m.Save(4, &x.AlwaysValid) + m.Save(5, &x.fdDir) } func (x *fdDirInode) afterLoad() {} -func (x *fdDirInode) load(m state.Map) { - m.Load("InodeNotSymlink", &x.InodeNotSymlink) - m.Load("InodeDirectoryNoNewChildren", &x.InodeDirectoryNoNewChildren) - m.Load("InodeAttrs", &x.InodeAttrs) - m.Load("OrderedChildren", &x.OrderedChildren) - m.Load("AlwaysValid", &x.AlwaysValid) - m.Load("fdDir", &x.fdDir) + +func (x *fdDirInode) StateLoad(m state.Source) { + m.Load(0, &x.InodeNotSymlink) + m.Load(1, &x.InodeDirectoryNoNewChildren) + m.Load(2, &x.InodeAttrs) + m.Load(3, &x.OrderedChildren) + m.Load(4, &x.AlwaysValid) + m.Load(5, &x.fdDir) +} + +func (x *fdSymlink) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.fdSymlink" +} + +func (x *fdSymlink) StateFields() []string { + return []string{ + "InodeAttrs", + "InodeNoopRefCount", + "InodeSymlink", + "task", + "fd", + } } func (x *fdSymlink) beforeSave() {} -func (x *fdSymlink) save(m state.Map) { + +func (x *fdSymlink) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeAttrs", &x.InodeAttrs) - m.Save("InodeNoopRefCount", &x.InodeNoopRefCount) - m.Save("InodeSymlink", &x.InodeSymlink) - m.Save("task", &x.task) - m.Save("fd", &x.fd) + m.Save(0, &x.InodeAttrs) + m.Save(1, &x.InodeNoopRefCount) + m.Save(2, &x.InodeSymlink) + m.Save(3, &x.task) + m.Save(4, &x.fd) } func (x *fdSymlink) afterLoad() {} -func (x *fdSymlink) load(m state.Map) { - m.Load("InodeAttrs", &x.InodeAttrs) - m.Load("InodeNoopRefCount", &x.InodeNoopRefCount) - m.Load("InodeSymlink", &x.InodeSymlink) - m.Load("task", &x.task) - m.Load("fd", &x.fd) + +func (x *fdSymlink) StateLoad(m state.Source) { + m.Load(0, &x.InodeAttrs) + m.Load(1, &x.InodeNoopRefCount) + m.Load(2, &x.InodeSymlink) + m.Load(3, &x.task) + m.Load(4, &x.fd) +} + +func (x *fdInfoDirInode) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.fdInfoDirInode" +} + +func (x *fdInfoDirInode) StateFields() []string { + return []string{ + "InodeNotSymlink", + "InodeDirectoryNoNewChildren", + "InodeAttrs", + "OrderedChildren", + "AlwaysValid", + "fdDir", + } } func (x *fdInfoDirInode) beforeSave() {} -func (x *fdInfoDirInode) save(m state.Map) { + +func (x *fdInfoDirInode) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeNotSymlink", &x.InodeNotSymlink) - m.Save("InodeDirectoryNoNewChildren", &x.InodeDirectoryNoNewChildren) - m.Save("InodeAttrs", &x.InodeAttrs) - m.Save("OrderedChildren", &x.OrderedChildren) - m.Save("AlwaysValid", &x.AlwaysValid) - m.Save("fdDir", &x.fdDir) + m.Save(0, &x.InodeNotSymlink) + m.Save(1, &x.InodeDirectoryNoNewChildren) + m.Save(2, &x.InodeAttrs) + m.Save(3, &x.OrderedChildren) + m.Save(4, &x.AlwaysValid) + m.Save(5, &x.fdDir) } func (x *fdInfoDirInode) afterLoad() {} -func (x *fdInfoDirInode) load(m state.Map) { - m.Load("InodeNotSymlink", &x.InodeNotSymlink) - m.Load("InodeDirectoryNoNewChildren", &x.InodeDirectoryNoNewChildren) - m.Load("InodeAttrs", &x.InodeAttrs) - m.Load("OrderedChildren", &x.OrderedChildren) - m.Load("AlwaysValid", &x.AlwaysValid) - m.Load("fdDir", &x.fdDir) + +func (x *fdInfoDirInode) StateLoad(m state.Source) { + m.Load(0, &x.InodeNotSymlink) + m.Load(1, &x.InodeDirectoryNoNewChildren) + m.Load(2, &x.InodeAttrs) + m.Load(3, &x.OrderedChildren) + m.Load(4, &x.AlwaysValid) + m.Load(5, &x.fdDir) +} + +func (x *fdInfoData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.fdInfoData" +} + +func (x *fdInfoData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "AtomicRefCount", + "task", + "fd", + } } func (x *fdInfoData) beforeSave() {} -func (x *fdInfoData) save(m state.Map) { + +func (x *fdInfoData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("AtomicRefCount", &x.AtomicRefCount) - m.Save("task", &x.task) - m.Save("fd", &x.fd) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.AtomicRefCount) + m.Save(2, &x.task) + m.Save(3, &x.fd) } func (x *fdInfoData) afterLoad() {} -func (x *fdInfoData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("AtomicRefCount", &x.AtomicRefCount) - m.Load("task", &x.task) - m.Load("fd", &x.fd) + +func (x *fdInfoData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.AtomicRefCount) + m.Load(2, &x.task) + m.Load(3, &x.fd) +} + +func (x *auxvData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.auxvData" +} + +func (x *auxvData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "task", + } } func (x *auxvData) beforeSave() {} -func (x *auxvData) save(m state.Map) { + +func (x *auxvData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("task", &x.task) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.task) } func (x *auxvData) afterLoad() {} -func (x *auxvData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("task", &x.task) + +func (x *auxvData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.task) +} + +func (x *cmdlineData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.cmdlineData" +} + +func (x *cmdlineData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "task", + "arg", + } } func (x *cmdlineData) beforeSave() {} -func (x *cmdlineData) save(m state.Map) { + +func (x *cmdlineData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("task", &x.task) - m.Save("arg", &x.arg) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.task) + m.Save(2, &x.arg) } func (x *cmdlineData) afterLoad() {} -func (x *cmdlineData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("task", &x.task) - m.Load("arg", &x.arg) + +func (x *cmdlineData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.task) + m.Load(2, &x.arg) +} + +func (x *commInode) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.commInode" +} + +func (x *commInode) StateFields() []string { + return []string{ + "DynamicBytesFile", + "task", + } } func (x *commInode) beforeSave() {} -func (x *commInode) save(m state.Map) { + +func (x *commInode) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("task", &x.task) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.task) } func (x *commInode) afterLoad() {} -func (x *commInode) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("task", &x.task) + +func (x *commInode) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.task) +} + +func (x *commData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.commData" +} + +func (x *commData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "task", + } } func (x *commData) beforeSave() {} -func (x *commData) save(m state.Map) { + +func (x *commData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("task", &x.task) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.task) } func (x *commData) afterLoad() {} -func (x *commData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("task", &x.task) + +func (x *commData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.task) +} + +func (x *idMapData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.idMapData" +} + +func (x *idMapData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "task", + "gids", + } } func (x *idMapData) beforeSave() {} -func (x *idMapData) save(m state.Map) { + +func (x *idMapData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("task", &x.task) - m.Save("gids", &x.gids) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.task) + m.Save(2, &x.gids) } func (x *idMapData) afterLoad() {} -func (x *idMapData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("task", &x.task) - m.Load("gids", &x.gids) + +func (x *idMapData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.task) + m.Load(2, &x.gids) +} + +func (x *mapsData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.mapsData" +} + +func (x *mapsData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "task", + } } func (x *mapsData) beforeSave() {} -func (x *mapsData) save(m state.Map) { + +func (x *mapsData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("task", &x.task) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.task) } func (x *mapsData) afterLoad() {} -func (x *mapsData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("task", &x.task) + +func (x *mapsData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.task) +} + +func (x *smapsData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.smapsData" +} + +func (x *smapsData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "task", + } } func (x *smapsData) beforeSave() {} -func (x *smapsData) save(m state.Map) { + +func (x *smapsData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("task", &x.task) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.task) } func (x *smapsData) afterLoad() {} -func (x *smapsData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("task", &x.task) + +func (x *smapsData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.task) +} + +func (x *taskStatData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.taskStatData" +} + +func (x *taskStatData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "task", + "tgstats", + "pidns", + } } func (x *taskStatData) beforeSave() {} -func (x *taskStatData) save(m state.Map) { + +func (x *taskStatData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("task", &x.task) - m.Save("tgstats", &x.tgstats) - m.Save("pidns", &x.pidns) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.task) + m.Save(2, &x.tgstats) + m.Save(3, &x.pidns) } func (x *taskStatData) afterLoad() {} -func (x *taskStatData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("task", &x.task) - m.Load("tgstats", &x.tgstats) - m.Load("pidns", &x.pidns) + +func (x *taskStatData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.task) + m.Load(2, &x.tgstats) + m.Load(3, &x.pidns) +} + +func (x *statmData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.statmData" +} + +func (x *statmData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "task", + } } func (x *statmData) beforeSave() {} -func (x *statmData) save(m state.Map) { + +func (x *statmData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("task", &x.task) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.task) } func (x *statmData) afterLoad() {} -func (x *statmData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("task", &x.task) + +func (x *statmData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.task) +} + +func (x *statusData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.statusData" +} + +func (x *statusData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "task", + "pidns", + } } func (x *statusData) beforeSave() {} -func (x *statusData) save(m state.Map) { + +func (x *statusData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("task", &x.task) - m.Save("pidns", &x.pidns) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.task) + m.Save(2, &x.pidns) } func (x *statusData) afterLoad() {} -func (x *statusData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("task", &x.task) - m.Load("pidns", &x.pidns) + +func (x *statusData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.task) + m.Load(2, &x.pidns) +} + +func (x *ioData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.ioData" +} + +func (x *ioData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "ioUsage", + } } func (x *ioData) beforeSave() {} -func (x *ioData) save(m state.Map) { + +func (x *ioData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("ioUsage", &x.ioUsage) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.ioUsage) } func (x *ioData) afterLoad() {} -func (x *ioData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("ioUsage", &x.ioUsage) + +func (x *ioData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.ioUsage) +} + +func (x *oomScoreAdj) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.oomScoreAdj" +} + +func (x *oomScoreAdj) StateFields() []string { + return []string{ + "DynamicBytesFile", + "task", + } } func (x *oomScoreAdj) beforeSave() {} -func (x *oomScoreAdj) save(m state.Map) { + +func (x *oomScoreAdj) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("task", &x.task) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.task) } func (x *oomScoreAdj) afterLoad() {} -func (x *oomScoreAdj) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("task", &x.task) + +func (x *oomScoreAdj) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.task) +} + +func (x *exeSymlink) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.exeSymlink" +} + +func (x *exeSymlink) StateFields() []string { + return []string{ + "InodeAttrs", + "InodeNoopRefCount", + "InodeSymlink", + "task", + } } func (x *exeSymlink) beforeSave() {} -func (x *exeSymlink) save(m state.Map) { + +func (x *exeSymlink) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeAttrs", &x.InodeAttrs) - m.Save("InodeNoopRefCount", &x.InodeNoopRefCount) - m.Save("InodeSymlink", &x.InodeSymlink) - m.Save("task", &x.task) + m.Save(0, &x.InodeAttrs) + m.Save(1, &x.InodeNoopRefCount) + m.Save(2, &x.InodeSymlink) + m.Save(3, &x.task) } func (x *exeSymlink) afterLoad() {} -func (x *exeSymlink) load(m state.Map) { - m.Load("InodeAttrs", &x.InodeAttrs) - m.Load("InodeNoopRefCount", &x.InodeNoopRefCount) - m.Load("InodeSymlink", &x.InodeSymlink) - m.Load("task", &x.task) + +func (x *exeSymlink) StateLoad(m state.Source) { + m.Load(0, &x.InodeAttrs) + m.Load(1, &x.InodeNoopRefCount) + m.Load(2, &x.InodeSymlink) + m.Load(3, &x.task) +} + +func (x *mountInfoData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.mountInfoData" +} + +func (x *mountInfoData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "task", + } } func (x *mountInfoData) beforeSave() {} -func (x *mountInfoData) save(m state.Map) { + +func (x *mountInfoData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("task", &x.task) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.task) } func (x *mountInfoData) afterLoad() {} -func (x *mountInfoData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("task", &x.task) + +func (x *mountInfoData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.task) +} + +func (x *mountsData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.mountsData" +} + +func (x *mountsData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "task", + } } func (x *mountsData) beforeSave() {} -func (x *mountsData) save(m state.Map) { + +func (x *mountsData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("task", &x.task) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.task) } func (x *mountsData) afterLoad() {} -func (x *mountsData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("task", &x.task) + +func (x *mountsData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.task) +} + +func (x *ifinet6) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.ifinet6" +} + +func (x *ifinet6) StateFields() []string { + return []string{ + "DynamicBytesFile", + "stack", + } } func (x *ifinet6) beforeSave() {} -func (x *ifinet6) save(m state.Map) { + +func (x *ifinet6) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("stack", &x.stack) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.stack) } func (x *ifinet6) afterLoad() {} -func (x *ifinet6) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("stack", &x.stack) + +func (x *ifinet6) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.stack) +} + +func (x *netDevData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.netDevData" +} + +func (x *netDevData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "stack", + } } func (x *netDevData) beforeSave() {} -func (x *netDevData) save(m state.Map) { + +func (x *netDevData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("stack", &x.stack) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.stack) } func (x *netDevData) afterLoad() {} -func (x *netDevData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("stack", &x.stack) + +func (x *netDevData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.stack) +} + +func (x *netUnixData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.netUnixData" +} + +func (x *netUnixData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "kernel", + } } func (x *netUnixData) beforeSave() {} -func (x *netUnixData) save(m state.Map) { + +func (x *netUnixData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("kernel", &x.kernel) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.kernel) } func (x *netUnixData) afterLoad() {} -func (x *netUnixData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("kernel", &x.kernel) + +func (x *netUnixData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.kernel) +} + +func (x *netTCPData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.netTCPData" +} + +func (x *netTCPData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "kernel", + } } func (x *netTCPData) beforeSave() {} -func (x *netTCPData) save(m state.Map) { + +func (x *netTCPData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("kernel", &x.kernel) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.kernel) } func (x *netTCPData) afterLoad() {} -func (x *netTCPData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("kernel", &x.kernel) + +func (x *netTCPData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.kernel) +} + +func (x *netTCP6Data) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.netTCP6Data" +} + +func (x *netTCP6Data) StateFields() []string { + return []string{ + "DynamicBytesFile", + "kernel", + } } func (x *netTCP6Data) beforeSave() {} -func (x *netTCP6Data) save(m state.Map) { + +func (x *netTCP6Data) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("kernel", &x.kernel) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.kernel) } func (x *netTCP6Data) afterLoad() {} -func (x *netTCP6Data) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("kernel", &x.kernel) + +func (x *netTCP6Data) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.kernel) +} + +func (x *netUDPData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.netUDPData" +} + +func (x *netUDPData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "kernel", + } } func (x *netUDPData) beforeSave() {} -func (x *netUDPData) save(m state.Map) { + +func (x *netUDPData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("kernel", &x.kernel) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.kernel) } func (x *netUDPData) afterLoad() {} -func (x *netUDPData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("kernel", &x.kernel) + +func (x *netUDPData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.kernel) +} + +func (x *netSnmpData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.netSnmpData" +} + +func (x *netSnmpData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "stack", + } } func (x *netSnmpData) beforeSave() {} -func (x *netSnmpData) save(m state.Map) { + +func (x *netSnmpData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("stack", &x.stack) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.stack) } func (x *netSnmpData) afterLoad() {} -func (x *netSnmpData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("stack", &x.stack) + +func (x *netSnmpData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.stack) +} + +func (x *netRouteData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.netRouteData" +} + +func (x *netRouteData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "stack", + } } func (x *netRouteData) beforeSave() {} -func (x *netRouteData) save(m state.Map) { + +func (x *netRouteData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("stack", &x.stack) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.stack) } func (x *netRouteData) afterLoad() {} -func (x *netRouteData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("stack", &x.stack) + +func (x *netRouteData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.stack) +} + +func (x *netStatData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.netStatData" +} + +func (x *netStatData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "stack", + } } func (x *netStatData) beforeSave() {} -func (x *netStatData) save(m state.Map) { + +func (x *netStatData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("stack", &x.stack) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.stack) } func (x *netStatData) afterLoad() {} -func (x *netStatData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("stack", &x.stack) + +func (x *netStatData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.stack) +} + +func (x *tasksInode) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.tasksInode" +} + +func (x *tasksInode) StateFields() []string { + return []string{ + "InodeNotSymlink", + "InodeDirectoryNoNewChildren", + "InodeAttrs", + "OrderedChildren", + "AlwaysValid", + "locks", + "fs", + "pidns", + "selfSymlink", + "threadSelfSymlink", + "cgroupControllers", + } } func (x *tasksInode) beforeSave() {} -func (x *tasksInode) save(m state.Map) { + +func (x *tasksInode) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeNotSymlink", &x.InodeNotSymlink) - m.Save("InodeDirectoryNoNewChildren", &x.InodeDirectoryNoNewChildren) - m.Save("InodeAttrs", &x.InodeAttrs) - m.Save("OrderedChildren", &x.OrderedChildren) - m.Save("AlwaysValid", &x.AlwaysValid) - m.Save("locks", &x.locks) - m.Save("fs", &x.fs) - m.Save("pidns", &x.pidns) - m.Save("selfSymlink", &x.selfSymlink) - m.Save("threadSelfSymlink", &x.threadSelfSymlink) - m.Save("cgroupControllers", &x.cgroupControllers) + m.Save(0, &x.InodeNotSymlink) + m.Save(1, &x.InodeDirectoryNoNewChildren) + m.Save(2, &x.InodeAttrs) + m.Save(3, &x.OrderedChildren) + m.Save(4, &x.AlwaysValid) + m.Save(5, &x.locks) + m.Save(6, &x.fs) + m.Save(7, &x.pidns) + m.Save(8, &x.selfSymlink) + m.Save(9, &x.threadSelfSymlink) + m.Save(10, &x.cgroupControllers) } func (x *tasksInode) afterLoad() {} -func (x *tasksInode) load(m state.Map) { - m.Load("InodeNotSymlink", &x.InodeNotSymlink) - m.Load("InodeDirectoryNoNewChildren", &x.InodeDirectoryNoNewChildren) - m.Load("InodeAttrs", &x.InodeAttrs) - m.Load("OrderedChildren", &x.OrderedChildren) - m.Load("AlwaysValid", &x.AlwaysValid) - m.Load("locks", &x.locks) - m.Load("fs", &x.fs) - m.Load("pidns", &x.pidns) - m.Load("selfSymlink", &x.selfSymlink) - m.Load("threadSelfSymlink", &x.threadSelfSymlink) - m.Load("cgroupControllers", &x.cgroupControllers) + +func (x *tasksInode) StateLoad(m state.Source) { + m.Load(0, &x.InodeNotSymlink) + m.Load(1, &x.InodeDirectoryNoNewChildren) + m.Load(2, &x.InodeAttrs) + m.Load(3, &x.OrderedChildren) + m.Load(4, &x.AlwaysValid) + m.Load(5, &x.locks) + m.Load(6, &x.fs) + m.Load(7, &x.pidns) + m.Load(8, &x.selfSymlink) + m.Load(9, &x.threadSelfSymlink) + m.Load(10, &x.cgroupControllers) +} + +func (x *statData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.statData" +} + +func (x *statData) StateFields() []string { + return []string{ + "dynamicBytesFileSetAttr", + } } func (x *statData) beforeSave() {} -func (x *statData) save(m state.Map) { + +func (x *statData) StateSave(m state.Sink) { x.beforeSave() - m.Save("dynamicBytesFileSetAttr", &x.dynamicBytesFileSetAttr) + m.Save(0, &x.dynamicBytesFileSetAttr) } func (x *statData) afterLoad() {} -func (x *statData) load(m state.Map) { - m.Load("dynamicBytesFileSetAttr", &x.dynamicBytesFileSetAttr) + +func (x *statData) StateLoad(m state.Source) { + m.Load(0, &x.dynamicBytesFileSetAttr) +} + +func (x *loadavgData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.loadavgData" +} + +func (x *loadavgData) StateFields() []string { + return []string{ + "dynamicBytesFileSetAttr", + } } func (x *loadavgData) beforeSave() {} -func (x *loadavgData) save(m state.Map) { + +func (x *loadavgData) StateSave(m state.Sink) { x.beforeSave() - m.Save("dynamicBytesFileSetAttr", &x.dynamicBytesFileSetAttr) + m.Save(0, &x.dynamicBytesFileSetAttr) } func (x *loadavgData) afterLoad() {} -func (x *loadavgData) load(m state.Map) { - m.Load("dynamicBytesFileSetAttr", &x.dynamicBytesFileSetAttr) + +func (x *loadavgData) StateLoad(m state.Source) { + m.Load(0, &x.dynamicBytesFileSetAttr) +} + +func (x *meminfoData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.meminfoData" +} + +func (x *meminfoData) StateFields() []string { + return []string{ + "dynamicBytesFileSetAttr", + } } func (x *meminfoData) beforeSave() {} -func (x *meminfoData) save(m state.Map) { + +func (x *meminfoData) StateSave(m state.Sink) { x.beforeSave() - m.Save("dynamicBytesFileSetAttr", &x.dynamicBytesFileSetAttr) + m.Save(0, &x.dynamicBytesFileSetAttr) } func (x *meminfoData) afterLoad() {} -func (x *meminfoData) load(m state.Map) { - m.Load("dynamicBytesFileSetAttr", &x.dynamicBytesFileSetAttr) + +func (x *meminfoData) StateLoad(m state.Source) { + m.Load(0, &x.dynamicBytesFileSetAttr) +} + +func (x *uptimeData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.uptimeData" +} + +func (x *uptimeData) StateFields() []string { + return []string{ + "dynamicBytesFileSetAttr", + } } func (x *uptimeData) beforeSave() {} -func (x *uptimeData) save(m state.Map) { + +func (x *uptimeData) StateSave(m state.Sink) { x.beforeSave() - m.Save("dynamicBytesFileSetAttr", &x.dynamicBytesFileSetAttr) + m.Save(0, &x.dynamicBytesFileSetAttr) } func (x *uptimeData) afterLoad() {} -func (x *uptimeData) load(m state.Map) { - m.Load("dynamicBytesFileSetAttr", &x.dynamicBytesFileSetAttr) + +func (x *uptimeData) StateLoad(m state.Source) { + m.Load(0, &x.dynamicBytesFileSetAttr) +} + +func (x *versionData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.versionData" +} + +func (x *versionData) StateFields() []string { + return []string{ + "dynamicBytesFileSetAttr", + } } func (x *versionData) beforeSave() {} -func (x *versionData) save(m state.Map) { + +func (x *versionData) StateSave(m state.Sink) { x.beforeSave() - m.Save("dynamicBytesFileSetAttr", &x.dynamicBytesFileSetAttr) + m.Save(0, &x.dynamicBytesFileSetAttr) } func (x *versionData) afterLoad() {} -func (x *versionData) load(m state.Map) { - m.Load("dynamicBytesFileSetAttr", &x.dynamicBytesFileSetAttr) + +func (x *versionData) StateLoad(m state.Source) { + m.Load(0, &x.dynamicBytesFileSetAttr) +} + +func (x *filesystemsData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.filesystemsData" +} + +func (x *filesystemsData) StateFields() []string { + return []string{ + "DynamicBytesFile", + } } func (x *filesystemsData) beforeSave() {} -func (x *filesystemsData) save(m state.Map) { + +func (x *filesystemsData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) + m.Save(0, &x.DynamicBytesFile) } func (x *filesystemsData) afterLoad() {} -func (x *filesystemsData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) + +func (x *filesystemsData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) +} + +func (x *mmapMinAddrData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.mmapMinAddrData" +} + +func (x *mmapMinAddrData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "k", + } } func (x *mmapMinAddrData) beforeSave() {} -func (x *mmapMinAddrData) save(m state.Map) { + +func (x *mmapMinAddrData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("k", &x.k) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.k) } func (x *mmapMinAddrData) afterLoad() {} -func (x *mmapMinAddrData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.Load("k", &x.k) + +func (x *mmapMinAddrData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.Load(1, &x.k) +} + +func (x *hostnameData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.hostnameData" +} + +func (x *hostnameData) StateFields() []string { + return []string{ + "DynamicBytesFile", + } } func (x *hostnameData) beforeSave() {} -func (x *hostnameData) save(m state.Map) { + +func (x *hostnameData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) + m.Save(0, &x.DynamicBytesFile) } func (x *hostnameData) afterLoad() {} -func (x *hostnameData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) + +func (x *hostnameData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) +} + +func (x *tcpSackData) StateTypeName() string { + return "pkg/sentry/fsimpl/proc.tcpSackData" +} + +func (x *tcpSackData) StateFields() []string { + return []string{ + "DynamicBytesFile", + "stack", + "enabled", + } } func (x *tcpSackData) beforeSave() {} -func (x *tcpSackData) save(m state.Map) { + +func (x *tcpSackData) StateSave(m state.Sink) { x.beforeSave() - m.Save("DynamicBytesFile", &x.DynamicBytesFile) - m.Save("stack", &x.stack) - m.Save("enabled", &x.enabled) + m.Save(0, &x.DynamicBytesFile) + m.Save(1, &x.stack) + m.Save(2, &x.enabled) } func (x *tcpSackData) afterLoad() {} -func (x *tcpSackData) load(m state.Map) { - m.Load("DynamicBytesFile", &x.DynamicBytesFile) - m.LoadWait("stack", &x.stack) - m.Load("enabled", &x.enabled) + +func (x *tcpSackData) StateLoad(m state.Source) { + m.Load(0, &x.DynamicBytesFile) + m.LoadWait(1, &x.stack) + m.Load(2, &x.enabled) } func init() { - state.Register("pkg/sentry/fsimpl/proc.FilesystemType", (*FilesystemType)(nil), state.Fns{Save: (*FilesystemType).save, Load: (*FilesystemType).load}) - state.Register("pkg/sentry/fsimpl/proc.subtasksInode", (*subtasksInode)(nil), state.Fns{Save: (*subtasksInode).save, Load: (*subtasksInode).load}) - state.Register("pkg/sentry/fsimpl/proc.taskInode", (*taskInode)(nil), state.Fns{Save: (*taskInode).save, Load: (*taskInode).load}) - state.Register("pkg/sentry/fsimpl/proc.fdDirInode", (*fdDirInode)(nil), state.Fns{Save: (*fdDirInode).save, Load: (*fdDirInode).load}) - state.Register("pkg/sentry/fsimpl/proc.fdSymlink", (*fdSymlink)(nil), state.Fns{Save: (*fdSymlink).save, Load: (*fdSymlink).load}) - state.Register("pkg/sentry/fsimpl/proc.fdInfoDirInode", (*fdInfoDirInode)(nil), state.Fns{Save: (*fdInfoDirInode).save, Load: (*fdInfoDirInode).load}) - state.Register("pkg/sentry/fsimpl/proc.fdInfoData", (*fdInfoData)(nil), state.Fns{Save: (*fdInfoData).save, Load: (*fdInfoData).load}) - state.Register("pkg/sentry/fsimpl/proc.auxvData", (*auxvData)(nil), state.Fns{Save: (*auxvData).save, Load: (*auxvData).load}) - state.Register("pkg/sentry/fsimpl/proc.cmdlineData", (*cmdlineData)(nil), state.Fns{Save: (*cmdlineData).save, Load: (*cmdlineData).load}) - state.Register("pkg/sentry/fsimpl/proc.commInode", (*commInode)(nil), state.Fns{Save: (*commInode).save, Load: (*commInode).load}) - state.Register("pkg/sentry/fsimpl/proc.commData", (*commData)(nil), state.Fns{Save: (*commData).save, Load: (*commData).load}) - state.Register("pkg/sentry/fsimpl/proc.idMapData", (*idMapData)(nil), state.Fns{Save: (*idMapData).save, Load: (*idMapData).load}) - state.Register("pkg/sentry/fsimpl/proc.mapsData", (*mapsData)(nil), state.Fns{Save: (*mapsData).save, Load: (*mapsData).load}) - state.Register("pkg/sentry/fsimpl/proc.smapsData", (*smapsData)(nil), state.Fns{Save: (*smapsData).save, Load: (*smapsData).load}) - state.Register("pkg/sentry/fsimpl/proc.taskStatData", (*taskStatData)(nil), state.Fns{Save: (*taskStatData).save, Load: (*taskStatData).load}) - state.Register("pkg/sentry/fsimpl/proc.statmData", (*statmData)(nil), state.Fns{Save: (*statmData).save, Load: (*statmData).load}) - state.Register("pkg/sentry/fsimpl/proc.statusData", (*statusData)(nil), state.Fns{Save: (*statusData).save, Load: (*statusData).load}) - state.Register("pkg/sentry/fsimpl/proc.ioData", (*ioData)(nil), state.Fns{Save: (*ioData).save, Load: (*ioData).load}) - state.Register("pkg/sentry/fsimpl/proc.oomScoreAdj", (*oomScoreAdj)(nil), state.Fns{Save: (*oomScoreAdj).save, Load: (*oomScoreAdj).load}) - state.Register("pkg/sentry/fsimpl/proc.exeSymlink", (*exeSymlink)(nil), state.Fns{Save: (*exeSymlink).save, Load: (*exeSymlink).load}) - state.Register("pkg/sentry/fsimpl/proc.mountInfoData", (*mountInfoData)(nil), state.Fns{Save: (*mountInfoData).save, Load: (*mountInfoData).load}) - state.Register("pkg/sentry/fsimpl/proc.mountsData", (*mountsData)(nil), state.Fns{Save: (*mountsData).save, Load: (*mountsData).load}) - state.Register("pkg/sentry/fsimpl/proc.ifinet6", (*ifinet6)(nil), state.Fns{Save: (*ifinet6).save, Load: (*ifinet6).load}) - state.Register("pkg/sentry/fsimpl/proc.netDevData", (*netDevData)(nil), state.Fns{Save: (*netDevData).save, Load: (*netDevData).load}) - state.Register("pkg/sentry/fsimpl/proc.netUnixData", (*netUnixData)(nil), state.Fns{Save: (*netUnixData).save, Load: (*netUnixData).load}) - state.Register("pkg/sentry/fsimpl/proc.netTCPData", (*netTCPData)(nil), state.Fns{Save: (*netTCPData).save, Load: (*netTCPData).load}) - state.Register("pkg/sentry/fsimpl/proc.netTCP6Data", (*netTCP6Data)(nil), state.Fns{Save: (*netTCP6Data).save, Load: (*netTCP6Data).load}) - state.Register("pkg/sentry/fsimpl/proc.netUDPData", (*netUDPData)(nil), state.Fns{Save: (*netUDPData).save, Load: (*netUDPData).load}) - state.Register("pkg/sentry/fsimpl/proc.netSnmpData", (*netSnmpData)(nil), state.Fns{Save: (*netSnmpData).save, Load: (*netSnmpData).load}) - state.Register("pkg/sentry/fsimpl/proc.netRouteData", (*netRouteData)(nil), state.Fns{Save: (*netRouteData).save, Load: (*netRouteData).load}) - state.Register("pkg/sentry/fsimpl/proc.netStatData", (*netStatData)(nil), state.Fns{Save: (*netStatData).save, Load: (*netStatData).load}) - state.Register("pkg/sentry/fsimpl/proc.tasksInode", (*tasksInode)(nil), state.Fns{Save: (*tasksInode).save, Load: (*tasksInode).load}) - state.Register("pkg/sentry/fsimpl/proc.statData", (*statData)(nil), state.Fns{Save: (*statData).save, Load: (*statData).load}) - state.Register("pkg/sentry/fsimpl/proc.loadavgData", (*loadavgData)(nil), state.Fns{Save: (*loadavgData).save, Load: (*loadavgData).load}) - state.Register("pkg/sentry/fsimpl/proc.meminfoData", (*meminfoData)(nil), state.Fns{Save: (*meminfoData).save, Load: (*meminfoData).load}) - state.Register("pkg/sentry/fsimpl/proc.uptimeData", (*uptimeData)(nil), state.Fns{Save: (*uptimeData).save, Load: (*uptimeData).load}) - state.Register("pkg/sentry/fsimpl/proc.versionData", (*versionData)(nil), state.Fns{Save: (*versionData).save, Load: (*versionData).load}) - state.Register("pkg/sentry/fsimpl/proc.filesystemsData", (*filesystemsData)(nil), state.Fns{Save: (*filesystemsData).save, Load: (*filesystemsData).load}) - state.Register("pkg/sentry/fsimpl/proc.mmapMinAddrData", (*mmapMinAddrData)(nil), state.Fns{Save: (*mmapMinAddrData).save, Load: (*mmapMinAddrData).load}) - state.Register("pkg/sentry/fsimpl/proc.hostnameData", (*hostnameData)(nil), state.Fns{Save: (*hostnameData).save, Load: (*hostnameData).load}) - state.Register("pkg/sentry/fsimpl/proc.tcpSackData", (*tcpSackData)(nil), state.Fns{Save: (*tcpSackData).save, Load: (*tcpSackData).load}) + state.Register((*FilesystemType)(nil)) + state.Register((*subtasksInode)(nil)) + state.Register((*taskInode)(nil)) + state.Register((*fdDirInode)(nil)) + state.Register((*fdSymlink)(nil)) + state.Register((*fdInfoDirInode)(nil)) + state.Register((*fdInfoData)(nil)) + state.Register((*auxvData)(nil)) + state.Register((*cmdlineData)(nil)) + state.Register((*commInode)(nil)) + state.Register((*commData)(nil)) + state.Register((*idMapData)(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((*oomScoreAdj)(nil)) + state.Register((*exeSymlink)(nil)) + state.Register((*mountInfoData)(nil)) + state.Register((*mountsData)(nil)) + state.Register((*ifinet6)(nil)) + state.Register((*netDevData)(nil)) + state.Register((*netUnixData)(nil)) + state.Register((*netTCPData)(nil)) + state.Register((*netTCP6Data)(nil)) + state.Register((*netUDPData)(nil)) + state.Register((*netSnmpData)(nil)) + state.Register((*netRouteData)(nil)) + state.Register((*netStatData)(nil)) + state.Register((*tasksInode)(nil)) + state.Register((*statData)(nil)) + state.Register((*loadavgData)(nil)) + state.Register((*meminfoData)(nil)) + state.Register((*uptimeData)(nil)) + state.Register((*versionData)(nil)) + state.Register((*filesystemsData)(nil)) + state.Register((*mmapMinAddrData)(nil)) + state.Register((*hostnameData)(nil)) + state.Register((*tcpSackData)(nil)) } diff --git a/pkg/sentry/fsimpl/tmpfs/dentry_list.go b/pkg/sentry/fsimpl/tmpfs/dentry_list.go index 9af621dd3..95e3d13d5 100644 --- a/pkg/sentry/fsimpl/tmpfs/dentry_list.go +++ b/pkg/sentry/fsimpl/tmpfs/dentry_list.go @@ -56,7 +56,7 @@ func (l *dentryList) Back() *dentry { // // NOTE: This is an O(n) operation. func (l *dentryList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (dentryElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *dentryList) Remove(e *dentry) { if prev != nil { dentryElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { dentryElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/fsimpl/tmpfs/tmpfs_state_autogen.go b/pkg/sentry/fsimpl/tmpfs/tmpfs_state_autogen.go index 10d8b49a6..1b617bd35 100644 --- a/pkg/sentry/fsimpl/tmpfs/tmpfs_state_autogen.go +++ b/pkg/sentry/fsimpl/tmpfs/tmpfs_state_autogen.go @@ -6,33 +6,59 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *dentryList) StateTypeName() string { + return "pkg/sentry/fsimpl/tmpfs.dentryList" +} + +func (x *dentryList) StateFields() []string { + return []string{ + "head", + "tail", + } +} + func (x *dentryList) beforeSave() {} -func (x *dentryList) save(m state.Map) { + +func (x *dentryList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *dentryList) afterLoad() {} -func (x *dentryList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *dentryList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *dentryEntry) StateTypeName() string { + return "pkg/sentry/fsimpl/tmpfs.dentryEntry" +} + +func (x *dentryEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *dentryEntry) beforeSave() {} -func (x *dentryEntry) save(m state.Map) { + +func (x *dentryEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *dentryEntry) afterLoad() {} -func (x *dentryEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *dentryEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) } func init() { - state.Register("pkg/sentry/fsimpl/tmpfs.dentryList", (*dentryList)(nil), state.Fns{Save: (*dentryList).save, Load: (*dentryList).load}) - state.Register("pkg/sentry/fsimpl/tmpfs.dentryEntry", (*dentryEntry)(nil), state.Fns{Save: (*dentryEntry).save, Load: (*dentryEntry).load}) + state.Register((*dentryList)(nil)) + state.Register((*dentryEntry)(nil)) } diff --git a/pkg/sentry/inet/inet_state_autogen.go b/pkg/sentry/inet/inet_state_autogen.go index d2985113b..dc382a657 100644 --- a/pkg/sentry/inet/inet_state_autogen.go +++ b/pkg/sentry/inet/inet_state_autogen.go @@ -6,35 +6,61 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *TCPBufferSize) StateTypeName() string { + return "pkg/sentry/inet.TCPBufferSize" +} + +func (x *TCPBufferSize) StateFields() []string { + return []string{ + "Min", + "Default", + "Max", + } +} + func (x *TCPBufferSize) beforeSave() {} -func (x *TCPBufferSize) save(m state.Map) { + +func (x *TCPBufferSize) StateSave(m state.Sink) { x.beforeSave() - m.Save("Min", &x.Min) - m.Save("Default", &x.Default) - m.Save("Max", &x.Max) + m.Save(0, &x.Min) + m.Save(1, &x.Default) + m.Save(2, &x.Max) } func (x *TCPBufferSize) afterLoad() {} -func (x *TCPBufferSize) load(m state.Map) { - m.Load("Min", &x.Min) - m.Load("Default", &x.Default) - m.Load("Max", &x.Max) + +func (x *TCPBufferSize) StateLoad(m state.Source) { + m.Load(0, &x.Min) + m.Load(1, &x.Default) + m.Load(2, &x.Max) +} + +func (x *Namespace) StateTypeName() string { + return "pkg/sentry/inet.Namespace" +} + +func (x *Namespace) StateFields() []string { + return []string{ + "creator", + "isRoot", + } } func (x *Namespace) beforeSave() {} -func (x *Namespace) save(m state.Map) { + +func (x *Namespace) StateSave(m state.Sink) { x.beforeSave() - m.Save("creator", &x.creator) - m.Save("isRoot", &x.isRoot) + m.Save(0, &x.creator) + m.Save(1, &x.isRoot) } -func (x *Namespace) load(m state.Map) { - m.LoadWait("creator", &x.creator) - m.Load("isRoot", &x.isRoot) +func (x *Namespace) StateLoad(m state.Source) { + m.LoadWait(0, &x.creator) + m.Load(1, &x.isRoot) m.AfterLoad(x.afterLoad) } func init() { - state.Register("pkg/sentry/inet.TCPBufferSize", (*TCPBufferSize)(nil), state.Fns{Save: (*TCPBufferSize).save, Load: (*TCPBufferSize).load}) - state.Register("pkg/sentry/inet.Namespace", (*Namespace)(nil), state.Fns{Save: (*Namespace).save, Load: (*Namespace).load}) + state.Register((*TCPBufferSize)(nil)) + state.Register((*Namespace)(nil)) } diff --git a/pkg/sentry/kernel/auth/auth_state_autogen.go b/pkg/sentry/kernel/auth/auth_state_autogen.go index 36e3576e8..7a710d06d 100644 --- a/pkg/sentry/kernel/auth/auth_state_autogen.go +++ b/pkg/sentry/kernel/auth/auth_state_autogen.go @@ -6,148 +6,261 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *Credentials) StateTypeName() string { + return "pkg/sentry/kernel/auth.Credentials" +} + +func (x *Credentials) StateFields() []string { + return []string{ + "RealKUID", + "EffectiveKUID", + "SavedKUID", + "RealKGID", + "EffectiveKGID", + "SavedKGID", + "ExtraKGIDs", + "PermittedCaps", + "InheritableCaps", + "EffectiveCaps", + "BoundingCaps", + "KeepCaps", + "UserNamespace", + } +} + func (x *Credentials) beforeSave() {} -func (x *Credentials) save(m state.Map) { + +func (x *Credentials) StateSave(m state.Sink) { x.beforeSave() - m.Save("RealKUID", &x.RealKUID) - m.Save("EffectiveKUID", &x.EffectiveKUID) - m.Save("SavedKUID", &x.SavedKUID) - m.Save("RealKGID", &x.RealKGID) - m.Save("EffectiveKGID", &x.EffectiveKGID) - m.Save("SavedKGID", &x.SavedKGID) - m.Save("ExtraKGIDs", &x.ExtraKGIDs) - m.Save("PermittedCaps", &x.PermittedCaps) - m.Save("InheritableCaps", &x.InheritableCaps) - m.Save("EffectiveCaps", &x.EffectiveCaps) - m.Save("BoundingCaps", &x.BoundingCaps) - m.Save("KeepCaps", &x.KeepCaps) - m.Save("UserNamespace", &x.UserNamespace) + m.Save(0, &x.RealKUID) + m.Save(1, &x.EffectiveKUID) + m.Save(2, &x.SavedKUID) + m.Save(3, &x.RealKGID) + m.Save(4, &x.EffectiveKGID) + m.Save(5, &x.SavedKGID) + m.Save(6, &x.ExtraKGIDs) + m.Save(7, &x.PermittedCaps) + m.Save(8, &x.InheritableCaps) + m.Save(9, &x.EffectiveCaps) + m.Save(10, &x.BoundingCaps) + m.Save(11, &x.KeepCaps) + m.Save(12, &x.UserNamespace) } func (x *Credentials) afterLoad() {} -func (x *Credentials) load(m state.Map) { - m.Load("RealKUID", &x.RealKUID) - m.Load("EffectiveKUID", &x.EffectiveKUID) - m.Load("SavedKUID", &x.SavedKUID) - m.Load("RealKGID", &x.RealKGID) - m.Load("EffectiveKGID", &x.EffectiveKGID) - m.Load("SavedKGID", &x.SavedKGID) - m.Load("ExtraKGIDs", &x.ExtraKGIDs) - m.Load("PermittedCaps", &x.PermittedCaps) - m.Load("InheritableCaps", &x.InheritableCaps) - m.Load("EffectiveCaps", &x.EffectiveCaps) - m.Load("BoundingCaps", &x.BoundingCaps) - m.Load("KeepCaps", &x.KeepCaps) - m.Load("UserNamespace", &x.UserNamespace) + +func (x *Credentials) StateLoad(m state.Source) { + m.Load(0, &x.RealKUID) + m.Load(1, &x.EffectiveKUID) + m.Load(2, &x.SavedKUID) + m.Load(3, &x.RealKGID) + m.Load(4, &x.EffectiveKGID) + m.Load(5, &x.SavedKGID) + m.Load(6, &x.ExtraKGIDs) + m.Load(7, &x.PermittedCaps) + m.Load(8, &x.InheritableCaps) + m.Load(9, &x.EffectiveCaps) + m.Load(10, &x.BoundingCaps) + m.Load(11, &x.KeepCaps) + m.Load(12, &x.UserNamespace) +} + +func (x *IDMapEntry) StateTypeName() string { + return "pkg/sentry/kernel/auth.IDMapEntry" +} + +func (x *IDMapEntry) StateFields() []string { + return []string{ + "FirstID", + "FirstParentID", + "Length", + } } func (x *IDMapEntry) beforeSave() {} -func (x *IDMapEntry) save(m state.Map) { + +func (x *IDMapEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("FirstID", &x.FirstID) - m.Save("FirstParentID", &x.FirstParentID) - m.Save("Length", &x.Length) + m.Save(0, &x.FirstID) + m.Save(1, &x.FirstParentID) + m.Save(2, &x.Length) } func (x *IDMapEntry) afterLoad() {} -func (x *IDMapEntry) load(m state.Map) { - m.Load("FirstID", &x.FirstID) - m.Load("FirstParentID", &x.FirstParentID) - m.Load("Length", &x.Length) + +func (x *IDMapEntry) StateLoad(m state.Source) { + m.Load(0, &x.FirstID) + m.Load(1, &x.FirstParentID) + m.Load(2, &x.Length) +} + +func (x *idMapRange) StateTypeName() string { + return "pkg/sentry/kernel/auth.idMapRange" +} + +func (x *idMapRange) StateFields() []string { + return []string{ + "Start", + "End", + } } func (x *idMapRange) beforeSave() {} -func (x *idMapRange) save(m state.Map) { + +func (x *idMapRange) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) + m.Save(0, &x.Start) + m.Save(1, &x.End) } func (x *idMapRange) afterLoad() {} -func (x *idMapRange) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) + +func (x *idMapRange) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) +} + +func (x *idMapSet) StateTypeName() string { + return "pkg/sentry/kernel/auth.idMapSet" +} + +func (x *idMapSet) StateFields() []string { + return []string{ + "root", + } } func (x *idMapSet) beforeSave() {} -func (x *idMapSet) save(m state.Map) { + +func (x *idMapSet) StateSave(m state.Sink) { x.beforeSave() var root *idMapSegmentDataSlices = x.saveRoot() - m.SaveValue("root", root) + m.SaveValue(0, root) } func (x *idMapSet) afterLoad() {} -func (x *idMapSet) load(m state.Map) { - m.LoadValue("root", new(*idMapSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*idMapSegmentDataSlices)) }) + +func (x *idMapSet) StateLoad(m state.Source) { + m.LoadValue(0, new(*idMapSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*idMapSegmentDataSlices)) }) +} + +func (x *idMapnode) StateTypeName() string { + return "pkg/sentry/kernel/auth.idMapnode" +} + +func (x *idMapnode) StateFields() []string { + return []string{ + "nrSegments", + "parent", + "parentIndex", + "hasChildren", + "maxGap", + "keys", + "values", + "children", + } } func (x *idMapnode) beforeSave() {} -func (x *idMapnode) save(m state.Map) { + +func (x *idMapnode) StateSave(m state.Sink) { x.beforeSave() - m.Save("nrSegments", &x.nrSegments) - m.Save("parent", &x.parent) - m.Save("parentIndex", &x.parentIndex) - m.Save("hasChildren", &x.hasChildren) - m.Save("maxGap", &x.maxGap) - m.Save("keys", &x.keys) - m.Save("values", &x.values) - m.Save("children", &x.children) + m.Save(0, &x.nrSegments) + m.Save(1, &x.parent) + m.Save(2, &x.parentIndex) + m.Save(3, &x.hasChildren) + m.Save(4, &x.maxGap) + m.Save(5, &x.keys) + m.Save(6, &x.values) + m.Save(7, &x.children) } func (x *idMapnode) afterLoad() {} -func (x *idMapnode) load(m state.Map) { - m.Load("nrSegments", &x.nrSegments) - m.Load("parent", &x.parent) - m.Load("parentIndex", &x.parentIndex) - m.Load("hasChildren", &x.hasChildren) - m.Load("maxGap", &x.maxGap) - m.Load("keys", &x.keys) - m.Load("values", &x.values) - m.Load("children", &x.children) + +func (x *idMapnode) StateLoad(m state.Source) { + m.Load(0, &x.nrSegments) + m.Load(1, &x.parent) + m.Load(2, &x.parentIndex) + m.Load(3, &x.hasChildren) + m.Load(4, &x.maxGap) + m.Load(5, &x.keys) + m.Load(6, &x.values) + m.Load(7, &x.children) +} + +func (x *idMapSegmentDataSlices) StateTypeName() string { + return "pkg/sentry/kernel/auth.idMapSegmentDataSlices" +} + +func (x *idMapSegmentDataSlices) StateFields() []string { + return []string{ + "Start", + "End", + "Values", + } } func (x *idMapSegmentDataSlices) beforeSave() {} -func (x *idMapSegmentDataSlices) save(m state.Map) { + +func (x *idMapSegmentDataSlices) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) - m.Save("Values", &x.Values) + m.Save(0, &x.Start) + m.Save(1, &x.End) + m.Save(2, &x.Values) } func (x *idMapSegmentDataSlices) afterLoad() {} -func (x *idMapSegmentDataSlices) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) - m.Load("Values", &x.Values) + +func (x *idMapSegmentDataSlices) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) + m.Load(2, &x.Values) +} + +func (x *UserNamespace) StateTypeName() string { + return "pkg/sentry/kernel/auth.UserNamespace" +} + +func (x *UserNamespace) StateFields() []string { + return []string{ + "parent", + "owner", + "uidMapFromParent", + "uidMapToParent", + "gidMapFromParent", + "gidMapToParent", + } } func (x *UserNamespace) beforeSave() {} -func (x *UserNamespace) save(m state.Map) { + +func (x *UserNamespace) StateSave(m state.Sink) { x.beforeSave() - m.Save("parent", &x.parent) - m.Save("owner", &x.owner) - m.Save("uidMapFromParent", &x.uidMapFromParent) - m.Save("uidMapToParent", &x.uidMapToParent) - m.Save("gidMapFromParent", &x.gidMapFromParent) - m.Save("gidMapToParent", &x.gidMapToParent) + m.Save(0, &x.parent) + m.Save(1, &x.owner) + m.Save(2, &x.uidMapFromParent) + m.Save(3, &x.uidMapToParent) + m.Save(4, &x.gidMapFromParent) + m.Save(5, &x.gidMapToParent) } func (x *UserNamespace) afterLoad() {} -func (x *UserNamespace) load(m state.Map) { - m.Load("parent", &x.parent) - m.Load("owner", &x.owner) - m.Load("uidMapFromParent", &x.uidMapFromParent) - m.Load("uidMapToParent", &x.uidMapToParent) - m.Load("gidMapFromParent", &x.gidMapFromParent) - m.Load("gidMapToParent", &x.gidMapToParent) + +func (x *UserNamespace) StateLoad(m state.Source) { + m.Load(0, &x.parent) + m.Load(1, &x.owner) + m.Load(2, &x.uidMapFromParent) + m.Load(3, &x.uidMapToParent) + m.Load(4, &x.gidMapFromParent) + m.Load(5, &x.gidMapToParent) } func init() { - state.Register("pkg/sentry/kernel/auth.Credentials", (*Credentials)(nil), state.Fns{Save: (*Credentials).save, Load: (*Credentials).load}) - state.Register("pkg/sentry/kernel/auth.IDMapEntry", (*IDMapEntry)(nil), state.Fns{Save: (*IDMapEntry).save, Load: (*IDMapEntry).load}) - state.Register("pkg/sentry/kernel/auth.idMapRange", (*idMapRange)(nil), state.Fns{Save: (*idMapRange).save, Load: (*idMapRange).load}) - state.Register("pkg/sentry/kernel/auth.idMapSet", (*idMapSet)(nil), state.Fns{Save: (*idMapSet).save, Load: (*idMapSet).load}) - state.Register("pkg/sentry/kernel/auth.idMapnode", (*idMapnode)(nil), state.Fns{Save: (*idMapnode).save, Load: (*idMapnode).load}) - state.Register("pkg/sentry/kernel/auth.idMapSegmentDataSlices", (*idMapSegmentDataSlices)(nil), state.Fns{Save: (*idMapSegmentDataSlices).save, Load: (*idMapSegmentDataSlices).load}) - state.Register("pkg/sentry/kernel/auth.UserNamespace", (*UserNamespace)(nil), state.Fns{Save: (*UserNamespace).save, Load: (*UserNamespace).load}) + state.Register((*Credentials)(nil)) + state.Register((*IDMapEntry)(nil)) + state.Register((*idMapRange)(nil)) + state.Register((*idMapSet)(nil)) + state.Register((*idMapnode)(nil)) + state.Register((*idMapSegmentDataSlices)(nil)) + state.Register((*UserNamespace)(nil)) } diff --git a/pkg/sentry/kernel/auth/auth_unsafe_state_autogen.go b/pkg/sentry/kernel/auth/auth_unsafe_state_autogen.go index 6589b612c..0a3507dd5 100644 --- a/pkg/sentry/kernel/auth/auth_unsafe_state_autogen.go +++ b/pkg/sentry/kernel/auth/auth_unsafe_state_autogen.go @@ -6,18 +6,30 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *AtomicPtrCredentials) StateTypeName() string { + return "pkg/sentry/kernel/auth.AtomicPtrCredentials" +} + +func (x *AtomicPtrCredentials) StateFields() []string { + return []string{ + "ptr", + } +} + func (x *AtomicPtrCredentials) beforeSave() {} -func (x *AtomicPtrCredentials) save(m state.Map) { + +func (x *AtomicPtrCredentials) StateSave(m state.Sink) { x.beforeSave() var ptr *Credentials = x.savePtr() - m.SaveValue("ptr", ptr) + m.SaveValue(0, ptr) } func (x *AtomicPtrCredentials) afterLoad() {} -func (x *AtomicPtrCredentials) load(m state.Map) { - m.LoadValue("ptr", new(*Credentials), func(y interface{}) { x.loadPtr(y.(*Credentials)) }) + +func (x *AtomicPtrCredentials) StateLoad(m state.Source) { + m.LoadValue(0, new(*Credentials), func(y interface{}) { x.loadPtr(y.(*Credentials)) }) } func init() { - state.Register("pkg/sentry/kernel/auth.AtomicPtrCredentials", (*AtomicPtrCredentials)(nil), state.Fns{Save: (*AtomicPtrCredentials).save, Load: (*AtomicPtrCredentials).load}) + state.Register((*AtomicPtrCredentials)(nil)) } diff --git a/pkg/sentry/kernel/epoll/epoll_list.go b/pkg/sentry/kernel/epoll/epoll_list.go index a018f7b5c..56d05c770 100644 --- a/pkg/sentry/kernel/epoll/epoll_list.go +++ b/pkg/sentry/kernel/epoll/epoll_list.go @@ -56,7 +56,7 @@ func (l *pollEntryList) Back() *pollEntry { // // NOTE: This is an O(n) operation. func (l *pollEntryList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (pollEntryElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *pollEntryList) Remove(e *pollEntry) { if prev != nil { pollEntryElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { pollEntryElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/kernel/epoll/epoll_state_autogen.go b/pkg/sentry/kernel/epoll/epoll_state_autogen.go index da3150465..3b9d76751 100644 --- a/pkg/sentry/kernel/epoll/epoll_state_autogen.go +++ b/pkg/sentry/kernel/epoll/epoll_state_autogen.go @@ -6,108 +6,177 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *FileIdentifier) StateTypeName() string { + return "pkg/sentry/kernel/epoll.FileIdentifier" +} + +func (x *FileIdentifier) StateFields() []string { + return []string{ + "File", + "Fd", + } +} + func (x *FileIdentifier) beforeSave() {} -func (x *FileIdentifier) save(m state.Map) { + +func (x *FileIdentifier) StateSave(m state.Sink) { x.beforeSave() - m.Save("File", &x.File) - m.Save("Fd", &x.Fd) + m.Save(0, &x.File) + m.Save(1, &x.Fd) } func (x *FileIdentifier) afterLoad() {} -func (x *FileIdentifier) load(m state.Map) { - m.LoadWait("File", &x.File) - m.Load("Fd", &x.Fd) + +func (x *FileIdentifier) StateLoad(m state.Source) { + m.LoadWait(0, &x.File) + m.Load(1, &x.Fd) +} + +func (x *pollEntry) StateTypeName() string { + return "pkg/sentry/kernel/epoll.pollEntry" +} + +func (x *pollEntry) StateFields() []string { + return []string{ + "pollEntryEntry", + "id", + "userData", + "mask", + "flags", + "epoll", + } } func (x *pollEntry) beforeSave() {} -func (x *pollEntry) save(m state.Map) { + +func (x *pollEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("pollEntryEntry", &x.pollEntryEntry) - m.Save("id", &x.id) - m.Save("userData", &x.userData) - m.Save("mask", &x.mask) - m.Save("flags", &x.flags) - m.Save("epoll", &x.epoll) -} - -func (x *pollEntry) load(m state.Map) { - m.Load("pollEntryEntry", &x.pollEntryEntry) - m.LoadWait("id", &x.id) - m.Load("userData", &x.userData) - m.Load("mask", &x.mask) - m.Load("flags", &x.flags) - m.Load("epoll", &x.epoll) + m.Save(0, &x.pollEntryEntry) + m.Save(1, &x.id) + m.Save(2, &x.userData) + m.Save(3, &x.mask) + m.Save(4, &x.flags) + m.Save(5, &x.epoll) +} + +func (x *pollEntry) StateLoad(m state.Source) { + m.Load(0, &x.pollEntryEntry) + m.LoadWait(1, &x.id) + m.Load(2, &x.userData) + m.Load(3, &x.mask) + m.Load(4, &x.flags) + m.Load(5, &x.epoll) m.AfterLoad(x.afterLoad) } +func (x *EventPoll) StateTypeName() string { + return "pkg/sentry/kernel/epoll.EventPoll" +} + +func (x *EventPoll) StateFields() []string { + return []string{ + "files", + "readyList", + "waitingList", + "disabledList", + } +} + func (x *EventPoll) beforeSave() {} -func (x *EventPoll) save(m state.Map) { + +func (x *EventPoll) StateSave(m state.Sink) { x.beforeSave() if !state.IsZeroValue(&x.FilePipeSeek) { - m.Failf("FilePipeSeek is %#v, expected zero", &x.FilePipeSeek) + state.Failf("FilePipeSeek is %#v, expected zero", &x.FilePipeSeek) } if !state.IsZeroValue(&x.FileNotDirReaddir) { - m.Failf("FileNotDirReaddir is %#v, expected zero", &x.FileNotDirReaddir) + state.Failf("FileNotDirReaddir is %#v, expected zero", &x.FileNotDirReaddir) } if !state.IsZeroValue(&x.FileNoFsync) { - m.Failf("FileNoFsync is %#v, expected zero", &x.FileNoFsync) + state.Failf("FileNoFsync is %#v, expected zero", &x.FileNoFsync) } if !state.IsZeroValue(&x.FileNoopFlush) { - m.Failf("FileNoopFlush is %#v, expected zero", &x.FileNoopFlush) + state.Failf("FileNoopFlush is %#v, expected zero", &x.FileNoopFlush) } if !state.IsZeroValue(&x.FileNoIoctl) { - m.Failf("FileNoIoctl is %#v, expected zero", &x.FileNoIoctl) + state.Failf("FileNoIoctl is %#v, expected zero", &x.FileNoIoctl) } if !state.IsZeroValue(&x.FileNoMMap) { - m.Failf("FileNoMMap is %#v, expected zero", &x.FileNoMMap) + state.Failf("FileNoMMap is %#v, expected zero", &x.FileNoMMap) } if !state.IsZeroValue(&x.Queue) { - m.Failf("Queue is %#v, expected zero", &x.Queue) + state.Failf("Queue is %#v, expected zero", &x.Queue) } - m.Save("files", &x.files) - m.Save("readyList", &x.readyList) - m.Save("waitingList", &x.waitingList) - m.Save("disabledList", &x.disabledList) + m.Save(0, &x.files) + m.Save(1, &x.readyList) + m.Save(2, &x.waitingList) + m.Save(3, &x.disabledList) } -func (x *EventPoll) load(m state.Map) { - m.Load("files", &x.files) - m.Load("readyList", &x.readyList) - m.Load("waitingList", &x.waitingList) - m.Load("disabledList", &x.disabledList) +func (x *EventPoll) StateLoad(m state.Source) { + m.Load(0, &x.files) + m.Load(1, &x.readyList) + m.Load(2, &x.waitingList) + m.Load(3, &x.disabledList) m.AfterLoad(x.afterLoad) } +func (x *pollEntryList) StateTypeName() string { + return "pkg/sentry/kernel/epoll.pollEntryList" +} + +func (x *pollEntryList) StateFields() []string { + return []string{ + "head", + "tail", + } +} + func (x *pollEntryList) beforeSave() {} -func (x *pollEntryList) save(m state.Map) { + +func (x *pollEntryList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *pollEntryList) afterLoad() {} -func (x *pollEntryList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *pollEntryList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *pollEntryEntry) StateTypeName() string { + return "pkg/sentry/kernel/epoll.pollEntryEntry" +} + +func (x *pollEntryEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *pollEntryEntry) beforeSave() {} -func (x *pollEntryEntry) save(m state.Map) { + +func (x *pollEntryEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *pollEntryEntry) afterLoad() {} -func (x *pollEntryEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *pollEntryEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) } func init() { - state.Register("pkg/sentry/kernel/epoll.FileIdentifier", (*FileIdentifier)(nil), state.Fns{Save: (*FileIdentifier).save, Load: (*FileIdentifier).load}) - state.Register("pkg/sentry/kernel/epoll.pollEntry", (*pollEntry)(nil), state.Fns{Save: (*pollEntry).save, Load: (*pollEntry).load}) - state.Register("pkg/sentry/kernel/epoll.EventPoll", (*EventPoll)(nil), state.Fns{Save: (*EventPoll).save, Load: (*EventPoll).load}) - state.Register("pkg/sentry/kernel/epoll.pollEntryList", (*pollEntryList)(nil), state.Fns{Save: (*pollEntryList).save, Load: (*pollEntryList).load}) - state.Register("pkg/sentry/kernel/epoll.pollEntryEntry", (*pollEntryEntry)(nil), state.Fns{Save: (*pollEntryEntry).save, Load: (*pollEntryEntry).load}) + state.Register((*FileIdentifier)(nil)) + state.Register((*pollEntry)(nil)) + state.Register((*EventPoll)(nil)) + state.Register((*pollEntryList)(nil)) + state.Register((*pollEntryEntry)(nil)) } diff --git a/pkg/sentry/kernel/eventfd/eventfd_state_autogen.go b/pkg/sentry/kernel/eventfd/eventfd_state_autogen.go index 636d80ea9..72a285daa 100644 --- a/pkg/sentry/kernel/eventfd/eventfd_state_autogen.go +++ b/pkg/sentry/kernel/eventfd/eventfd_state_autogen.go @@ -6,24 +6,38 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *EventOperations) StateTypeName() string { + return "pkg/sentry/kernel/eventfd.EventOperations" +} + +func (x *EventOperations) StateFields() []string { + return []string{ + "val", + "semMode", + "hostfd", + } +} + func (x *EventOperations) beforeSave() {} -func (x *EventOperations) save(m state.Map) { + +func (x *EventOperations) StateSave(m state.Sink) { x.beforeSave() if !state.IsZeroValue(&x.wq) { - m.Failf("wq is %#v, expected zero", &x.wq) + state.Failf("wq is %#v, expected zero", &x.wq) } - m.Save("val", &x.val) - m.Save("semMode", &x.semMode) - m.Save("hostfd", &x.hostfd) + m.Save(0, &x.val) + m.Save(1, &x.semMode) + m.Save(2, &x.hostfd) } func (x *EventOperations) afterLoad() {} -func (x *EventOperations) load(m state.Map) { - m.Load("val", &x.val) - m.Load("semMode", &x.semMode) - m.Load("hostfd", &x.hostfd) + +func (x *EventOperations) StateLoad(m state.Source) { + m.Load(0, &x.val) + m.Load(1, &x.semMode) + m.Load(2, &x.hostfd) } func init() { - state.Register("pkg/sentry/kernel/eventfd.EventOperations", (*EventOperations)(nil), state.Fns{Save: (*EventOperations).save, Load: (*EventOperations).load}) + state.Register((*EventOperations)(nil)) } diff --git a/pkg/sentry/kernel/fasync/fasync_state_autogen.go b/pkg/sentry/kernel/fasync/fasync_state_autogen.go index fdcd48f64..8da4a1b44 100644 --- a/pkg/sentry/kernel/fasync/fasync_state_autogen.go +++ b/pkg/sentry/kernel/fasync/fasync_state_autogen.go @@ -6,27 +6,44 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *FileAsync) StateTypeName() string { + return "pkg/sentry/kernel/fasync.FileAsync" +} + +func (x *FileAsync) StateFields() []string { + return []string{ + "e", + "requester", + "registered", + "recipientPG", + "recipientTG", + "recipientT", + } +} + func (x *FileAsync) beforeSave() {} -func (x *FileAsync) save(m state.Map) { + +func (x *FileAsync) StateSave(m state.Sink) { x.beforeSave() - m.Save("e", &x.e) - m.Save("requester", &x.requester) - m.Save("registered", &x.registered) - m.Save("recipientPG", &x.recipientPG) - m.Save("recipientTG", &x.recipientTG) - m.Save("recipientT", &x.recipientT) + m.Save(0, &x.e) + m.Save(1, &x.requester) + m.Save(2, &x.registered) + m.Save(3, &x.recipientPG) + m.Save(4, &x.recipientTG) + m.Save(5, &x.recipientT) } func (x *FileAsync) afterLoad() {} -func (x *FileAsync) load(m state.Map) { - m.Load("e", &x.e) - m.Load("requester", &x.requester) - m.Load("registered", &x.registered) - m.Load("recipientPG", &x.recipientPG) - m.Load("recipientTG", &x.recipientTG) - m.Load("recipientT", &x.recipientT) + +func (x *FileAsync) StateLoad(m state.Source) { + m.Load(0, &x.e) + m.Load(1, &x.requester) + m.Load(2, &x.registered) + m.Load(3, &x.recipientPG) + m.Load(4, &x.recipientTG) + m.Load(5, &x.recipientT) } func init() { - state.Register("pkg/sentry/kernel/fasync.FileAsync", (*FileAsync)(nil), state.Fns{Save: (*FileAsync).save, Load: (*FileAsync).load}) + state.Register((*FileAsync)(nil)) } diff --git a/pkg/sentry/kernel/futex/futex_state_autogen.go b/pkg/sentry/kernel/futex/futex_state_autogen.go index 12a0788ff..13e9a97d0 100644 --- a/pkg/sentry/kernel/futex/futex_state_autogen.go +++ b/pkg/sentry/kernel/futex/futex_state_autogen.go @@ -6,61 +6,109 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *bucket) StateTypeName() string { + return "pkg/sentry/kernel/futex.bucket" +} + +func (x *bucket) StateFields() []string { + return []string{} +} + func (x *bucket) beforeSave() {} -func (x *bucket) save(m state.Map) { + +func (x *bucket) StateSave(m state.Sink) { x.beforeSave() if !state.IsZeroValue(&x.waiters) { - m.Failf("waiters is %#v, expected zero", &x.waiters) + state.Failf("waiters is %#v, expected zero", &x.waiters) } } func (x *bucket) afterLoad() {} -func (x *bucket) load(m state.Map) { + +func (x *bucket) StateLoad(m state.Source) { +} + +func (x *Manager) StateTypeName() string { + return "pkg/sentry/kernel/futex.Manager" +} + +func (x *Manager) StateFields() []string { + return []string{ + "sharedBucket", + } } func (x *Manager) beforeSave() {} -func (x *Manager) save(m state.Map) { + +func (x *Manager) StateSave(m state.Sink) { x.beforeSave() if !state.IsZeroValue(&x.privateBuckets) { - m.Failf("privateBuckets is %#v, expected zero", &x.privateBuckets) + state.Failf("privateBuckets is %#v, expected zero", &x.privateBuckets) } - m.Save("sharedBucket", &x.sharedBucket) + m.Save(0, &x.sharedBucket) } func (x *Manager) afterLoad() {} -func (x *Manager) load(m state.Map) { - m.Load("sharedBucket", &x.sharedBucket) + +func (x *Manager) StateLoad(m state.Source) { + m.Load(0, &x.sharedBucket) +} + +func (x *waiterList) StateTypeName() string { + return "pkg/sentry/kernel/futex.waiterList" +} + +func (x *waiterList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *waiterList) beforeSave() {} -func (x *waiterList) save(m state.Map) { + +func (x *waiterList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *waiterList) afterLoad() {} -func (x *waiterList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *waiterList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *waiterEntry) StateTypeName() string { + return "pkg/sentry/kernel/futex.waiterEntry" +} + +func (x *waiterEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *waiterEntry) beforeSave() {} -func (x *waiterEntry) save(m state.Map) { + +func (x *waiterEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *waiterEntry) afterLoad() {} -func (x *waiterEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *waiterEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) } func init() { - state.Register("pkg/sentry/kernel/futex.bucket", (*bucket)(nil), state.Fns{Save: (*bucket).save, Load: (*bucket).load}) - state.Register("pkg/sentry/kernel/futex.Manager", (*Manager)(nil), state.Fns{Save: (*Manager).save, Load: (*Manager).load}) - state.Register("pkg/sentry/kernel/futex.waiterList", (*waiterList)(nil), state.Fns{Save: (*waiterList).save, Load: (*waiterList).load}) - state.Register("pkg/sentry/kernel/futex.waiterEntry", (*waiterEntry)(nil), state.Fns{Save: (*waiterEntry).save, Load: (*waiterEntry).load}) + state.Register((*bucket)(nil)) + state.Register((*Manager)(nil)) + state.Register((*waiterList)(nil)) + state.Register((*waiterEntry)(nil)) } diff --git a/pkg/sentry/kernel/futex/futex_unsafe_state_autogen.go b/pkg/sentry/kernel/futex/futex_unsafe_state_autogen.go index 7fc038fce..244cdb502 100644 --- a/pkg/sentry/kernel/futex/futex_unsafe_state_autogen.go +++ b/pkg/sentry/kernel/futex/futex_unsafe_state_autogen.go @@ -6,18 +6,30 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *AtomicPtrBucket) StateTypeName() string { + return "pkg/sentry/kernel/futex.AtomicPtrBucket" +} + +func (x *AtomicPtrBucket) StateFields() []string { + return []string{ + "ptr", + } +} + func (x *AtomicPtrBucket) beforeSave() {} -func (x *AtomicPtrBucket) save(m state.Map) { + +func (x *AtomicPtrBucket) StateSave(m state.Sink) { x.beforeSave() var ptr *bucket = x.savePtr() - m.SaveValue("ptr", ptr) + m.SaveValue(0, ptr) } func (x *AtomicPtrBucket) afterLoad() {} -func (x *AtomicPtrBucket) load(m state.Map) { - m.LoadValue("ptr", new(*bucket), func(y interface{}) { x.loadPtr(y.(*bucket)) }) + +func (x *AtomicPtrBucket) StateLoad(m state.Source) { + m.LoadValue(0, new(*bucket), func(y interface{}) { x.loadPtr(y.(*bucket)) }) } func init() { - state.Register("pkg/sentry/kernel/futex.AtomicPtrBucket", (*AtomicPtrBucket)(nil), state.Fns{Save: (*AtomicPtrBucket).save, Load: (*AtomicPtrBucket).load}) + state.Register((*AtomicPtrBucket)(nil)) } diff --git a/pkg/sentry/kernel/futex/waiter_list.go b/pkg/sentry/kernel/futex/waiter_list.go index 1b7a92b62..ab6997b26 100644 --- a/pkg/sentry/kernel/futex/waiter_list.go +++ b/pkg/sentry/kernel/futex/waiter_list.go @@ -56,7 +56,7 @@ func (l *waiterList) Back() *Waiter { // // NOTE: This is an O(n) operation. func (l *waiterList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (waiterElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *waiterList) Remove(e *Waiter) { if prev != nil { waiterElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { waiterElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index 554a42e05..2177b785a 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -34,7 +34,6 @@ package kernel import ( "errors" "fmt" - "io" "path/filepath" "sync/atomic" "time" @@ -73,6 +72,7 @@ import ( "gvisor.dev/gvisor/pkg/sentry/uniqueid" "gvisor.dev/gvisor/pkg/sentry/vfs" "gvisor.dev/gvisor/pkg/state" + "gvisor.dev/gvisor/pkg/state/wire" "gvisor.dev/gvisor/pkg/sync" "gvisor.dev/gvisor/pkg/tcpip" ) @@ -417,7 +417,7 @@ func (k *Kernel) Init(args InitKernelArgs) error { // SaveTo saves the state of k to w. // // Preconditions: The kernel must be paused throughout the call to SaveTo. -func (k *Kernel) SaveTo(w io.Writer) error { +func (k *Kernel) SaveTo(w wire.Writer) error { saveStart := time.Now() ctx := k.SupervisorContext() @@ -473,18 +473,18 @@ func (k *Kernel) SaveTo(w io.Writer) error { // // N.B. This will also be saved along with the full kernel save below. cpuidStart := time.Now() - if err := state.Save(k.SupervisorContext(), w, k.FeatureSet(), nil); err != nil { + if _, err := state.Save(k.SupervisorContext(), w, k.FeatureSet()); err != nil { return err } log.Infof("CPUID save took [%s].", time.Since(cpuidStart)) // Save the kernel state. kernelStart := time.Now() - var stats state.Stats - if err := state.Save(k.SupervisorContext(), w, k, &stats); err != nil { + stats, err := state.Save(k.SupervisorContext(), w, k) + if err != nil { return err } - log.Infof("Kernel save stats: %s", &stats) + log.Infof("Kernel save stats: %s", stats.String()) log.Infof("Kernel save took [%s].", time.Since(kernelStart)) // Save the memory file's state. @@ -629,7 +629,7 @@ func (ts *TaskSet) unregisterEpollWaiters() { } // LoadFrom returns a new Kernel loaded from args. -func (k *Kernel) LoadFrom(r io.Reader, net inet.Stack, clocks sentrytime.Clocks) error { +func (k *Kernel) LoadFrom(r wire.Reader, net inet.Stack, clocks sentrytime.Clocks) error { loadStart := time.Now() initAppCores := k.applicationCores @@ -640,7 +640,7 @@ func (k *Kernel) LoadFrom(r io.Reader, net inet.Stack, clocks sentrytime.Clocks) // don't need to explicitly install it in the Kernel. cpuidStart := time.Now() var features cpuid.FeatureSet - if err := state.Load(k.SupervisorContext(), r, &features, nil); err != nil { + if _, err := state.Load(k.SupervisorContext(), r, &features); err != nil { return err } log.Infof("CPUID load took [%s].", time.Since(cpuidStart)) @@ -655,11 +655,11 @@ func (k *Kernel) LoadFrom(r io.Reader, net inet.Stack, clocks sentrytime.Clocks) // Load the kernel state. kernelStart := time.Now() - var stats state.Stats - if err := state.Load(k.SupervisorContext(), r, k, &stats); err != nil { + stats, err := state.Load(k.SupervisorContext(), r, k) + if err != nil { return err } - log.Infof("Kernel load stats: %s", &stats) + log.Infof("Kernel load stats: %s", stats.String()) log.Infof("Kernel load took [%s].", time.Since(kernelStart)) // rootNetworkNamespace should be populated after loading the state file. diff --git a/pkg/sentry/kernel/kernel_opts_state_autogen.go b/pkg/sentry/kernel/kernel_opts_state_autogen.go index 9ed7e27c9..a01604159 100644 --- a/pkg/sentry/kernel/kernel_opts_state_autogen.go +++ b/pkg/sentry/kernel/kernel_opts_state_autogen.go @@ -6,15 +6,25 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *SpecialOpts) StateTypeName() string { + return "pkg/sentry/kernel.SpecialOpts" +} + +func (x *SpecialOpts) StateFields() []string { + return []string{} +} + func (x *SpecialOpts) beforeSave() {} -func (x *SpecialOpts) save(m state.Map) { + +func (x *SpecialOpts) StateSave(m state.Sink) { x.beforeSave() } func (x *SpecialOpts) afterLoad() {} -func (x *SpecialOpts) load(m state.Map) { + +func (x *SpecialOpts) StateLoad(m state.Source) { } func init() { - state.Register("pkg/sentry/kernel.SpecialOpts", (*SpecialOpts)(nil), state.Fns{Save: (*SpecialOpts).save, Load: (*SpecialOpts).load}) + state.Register((*SpecialOpts)(nil)) } diff --git a/pkg/sentry/kernel/kernel_state_autogen.go b/pkg/sentry/kernel/kernel_state_autogen.go index 0c74e8c7c..8f184e712 100644 --- a/pkg/sentry/kernel/kernel_state_autogen.go +++ b/pkg/sentry/kernel/kernel_state_autogen.go @@ -9,1229 +9,2210 @@ import ( "gvisor.dev/gvisor/pkg/tcpip" ) +func (x *abstractEndpoint) StateTypeName() string { + return "pkg/sentry/kernel.abstractEndpoint" +} + +func (x *abstractEndpoint) StateFields() []string { + return []string{ + "ep", + "wr", + "name", + "ns", + } +} + func (x *abstractEndpoint) beforeSave() {} -func (x *abstractEndpoint) save(m state.Map) { + +func (x *abstractEndpoint) StateSave(m state.Sink) { x.beforeSave() - m.Save("ep", &x.ep) - m.Save("wr", &x.wr) - m.Save("name", &x.name) - m.Save("ns", &x.ns) + m.Save(0, &x.ep) + m.Save(1, &x.wr) + m.Save(2, &x.name) + m.Save(3, &x.ns) } func (x *abstractEndpoint) afterLoad() {} -func (x *abstractEndpoint) load(m state.Map) { - m.Load("ep", &x.ep) - m.Load("wr", &x.wr) - m.Load("name", &x.name) - m.Load("ns", &x.ns) + +func (x *abstractEndpoint) StateLoad(m state.Source) { + m.Load(0, &x.ep) + m.Load(1, &x.wr) + m.Load(2, &x.name) + m.Load(3, &x.ns) +} + +func (x *AbstractSocketNamespace) StateTypeName() string { + return "pkg/sentry/kernel.AbstractSocketNamespace" +} + +func (x *AbstractSocketNamespace) StateFields() []string { + return []string{ + "endpoints", + } } func (x *AbstractSocketNamespace) beforeSave() {} -func (x *AbstractSocketNamespace) save(m state.Map) { + +func (x *AbstractSocketNamespace) StateSave(m state.Sink) { x.beforeSave() - m.Save("endpoints", &x.endpoints) + m.Save(0, &x.endpoints) } func (x *AbstractSocketNamespace) afterLoad() {} -func (x *AbstractSocketNamespace) load(m state.Map) { - m.Load("endpoints", &x.endpoints) + +func (x *AbstractSocketNamespace) StateLoad(m state.Source) { + m.Load(0, &x.endpoints) +} + +func (x *FDFlags) StateTypeName() string { + return "pkg/sentry/kernel.FDFlags" +} + +func (x *FDFlags) StateFields() []string { + return []string{ + "CloseOnExec", + } } func (x *FDFlags) beforeSave() {} -func (x *FDFlags) save(m state.Map) { + +func (x *FDFlags) StateSave(m state.Sink) { x.beforeSave() - m.Save("CloseOnExec", &x.CloseOnExec) + m.Save(0, &x.CloseOnExec) } func (x *FDFlags) afterLoad() {} -func (x *FDFlags) load(m state.Map) { - m.Load("CloseOnExec", &x.CloseOnExec) + +func (x *FDFlags) StateLoad(m state.Source) { + m.Load(0, &x.CloseOnExec) +} + +func (x *descriptor) StateTypeName() string { + return "pkg/sentry/kernel.descriptor" +} + +func (x *descriptor) StateFields() []string { + return []string{ + "file", + "fileVFS2", + "flags", + } } func (x *descriptor) beforeSave() {} -func (x *descriptor) save(m state.Map) { + +func (x *descriptor) StateSave(m state.Sink) { x.beforeSave() - m.Save("file", &x.file) - m.Save("fileVFS2", &x.fileVFS2) - m.Save("flags", &x.flags) + m.Save(0, &x.file) + m.Save(1, &x.fileVFS2) + m.Save(2, &x.flags) } func (x *descriptor) afterLoad() {} -func (x *descriptor) load(m state.Map) { - m.Load("file", &x.file) - m.Load("fileVFS2", &x.fileVFS2) - m.Load("flags", &x.flags) + +func (x *descriptor) StateLoad(m state.Source) { + m.Load(0, &x.file) + m.Load(1, &x.fileVFS2) + m.Load(2, &x.flags) +} + +func (x *FDTable) StateTypeName() string { + return "pkg/sentry/kernel.FDTable" +} + +func (x *FDTable) StateFields() []string { + return []string{ + "AtomicRefCount", + "k", + "next", + "used", + "descriptorTable", + } } func (x *FDTable) beforeSave() {} -func (x *FDTable) save(m state.Map) { + +func (x *FDTable) StateSave(m state.Sink) { x.beforeSave() var descriptorTable map[int32]descriptor = x.saveDescriptorTable() - m.SaveValue("descriptorTable", descriptorTable) - m.Save("AtomicRefCount", &x.AtomicRefCount) - m.Save("k", &x.k) - m.Save("next", &x.next) - m.Save("used", &x.used) + m.SaveValue(4, descriptorTable) + m.Save(0, &x.AtomicRefCount) + m.Save(1, &x.k) + m.Save(2, &x.next) + m.Save(3, &x.used) } func (x *FDTable) afterLoad() {} -func (x *FDTable) load(m state.Map) { - m.Load("AtomicRefCount", &x.AtomicRefCount) - m.Load("k", &x.k) - m.Load("next", &x.next) - m.Load("used", &x.used) - m.LoadValue("descriptorTable", new(map[int32]descriptor), func(y interface{}) { x.loadDescriptorTable(y.(map[int32]descriptor)) }) + +func (x *FDTable) StateLoad(m state.Source) { + m.Load(0, &x.AtomicRefCount) + m.Load(1, &x.k) + m.Load(2, &x.next) + m.Load(3, &x.used) + m.LoadValue(4, new(map[int32]descriptor), func(y interface{}) { x.loadDescriptorTable(y.(map[int32]descriptor)) }) +} + +func (x *FSContext) StateTypeName() string { + return "pkg/sentry/kernel.FSContext" +} + +func (x *FSContext) StateFields() []string { + return []string{ + "AtomicRefCount", + "root", + "rootVFS2", + "cwd", + "cwdVFS2", + "umask", + } } func (x *FSContext) beforeSave() {} -func (x *FSContext) save(m state.Map) { + +func (x *FSContext) StateSave(m state.Sink) { x.beforeSave() - m.Save("AtomicRefCount", &x.AtomicRefCount) - m.Save("root", &x.root) - m.Save("rootVFS2", &x.rootVFS2) - m.Save("cwd", &x.cwd) - m.Save("cwdVFS2", &x.cwdVFS2) - m.Save("umask", &x.umask) + m.Save(0, &x.AtomicRefCount) + m.Save(1, &x.root) + m.Save(2, &x.rootVFS2) + m.Save(3, &x.cwd) + m.Save(4, &x.cwdVFS2) + m.Save(5, &x.umask) } func (x *FSContext) afterLoad() {} -func (x *FSContext) load(m state.Map) { - m.Load("AtomicRefCount", &x.AtomicRefCount) - m.Load("root", &x.root) - m.Load("rootVFS2", &x.rootVFS2) - m.Load("cwd", &x.cwd) - m.Load("cwdVFS2", &x.cwdVFS2) - m.Load("umask", &x.umask) + +func (x *FSContext) StateLoad(m state.Source) { + m.Load(0, &x.AtomicRefCount) + m.Load(1, &x.root) + m.Load(2, &x.rootVFS2) + m.Load(3, &x.cwd) + m.Load(4, &x.cwdVFS2) + m.Load(5, &x.umask) +} + +func (x *IPCNamespace) StateTypeName() string { + return "pkg/sentry/kernel.IPCNamespace" +} + +func (x *IPCNamespace) StateFields() []string { + return []string{ + "userNS", + "semaphores", + "shms", + } } func (x *IPCNamespace) beforeSave() {} -func (x *IPCNamespace) save(m state.Map) { + +func (x *IPCNamespace) StateSave(m state.Sink) { x.beforeSave() - m.Save("userNS", &x.userNS) - m.Save("semaphores", &x.semaphores) - m.Save("shms", &x.shms) + m.Save(0, &x.userNS) + m.Save(1, &x.semaphores) + m.Save(2, &x.shms) } func (x *IPCNamespace) afterLoad() {} -func (x *IPCNamespace) load(m state.Map) { - m.Load("userNS", &x.userNS) - m.Load("semaphores", &x.semaphores) - m.Load("shms", &x.shms) + +func (x *IPCNamespace) StateLoad(m state.Source) { + m.Load(0, &x.userNS) + m.Load(1, &x.semaphores) + m.Load(2, &x.shms) +} + +func (x *Kernel) StateTypeName() string { + return "pkg/sentry/kernel.Kernel" +} + +func (x *Kernel) StateFields() []string { + return []string{ + "featureSet", + "timekeeper", + "tasks", + "rootUserNamespace", + "rootNetworkNamespace", + "applicationCores", + "useHostCores", + "extraAuxv", + "vdso", + "rootUTSNamespace", + "rootIPCNamespace", + "rootAbstractSocketNamespace", + "futexes", + "globalInit", + "realtimeClock", + "monotonicClock", + "syslog", + "runningTasks", + "cpuClock", + "cpuClockTickerDisabled", + "cpuClockTickerSetting", + "uniqueID", + "nextInotifyCookie", + "netlinkPorts", + "danglingEndpoints", + "sockets", + "nextSocketEntry", + "deviceRegistry", + "DirentCacheLimiter", + "SpecialOpts", + "vfs", + "hostMount", + "pipeMount", + "shmMount", + "socketMount", + "SleepForAddressSpaceActivation", + } } func (x *Kernel) beforeSave() {} -func (x *Kernel) save(m state.Map) { + +func (x *Kernel) StateSave(m state.Sink) { x.beforeSave() var danglingEndpoints []tcpip.Endpoint = x.saveDanglingEndpoints() - m.SaveValue("danglingEndpoints", danglingEndpoints) + m.SaveValue(24, danglingEndpoints) var deviceRegistry *device.Registry = x.saveDeviceRegistry() - m.SaveValue("deviceRegistry", deviceRegistry) - m.Save("featureSet", &x.featureSet) - m.Save("timekeeper", &x.timekeeper) - m.Save("tasks", &x.tasks) - m.Save("rootUserNamespace", &x.rootUserNamespace) - m.Save("rootNetworkNamespace", &x.rootNetworkNamespace) - m.Save("applicationCores", &x.applicationCores) - m.Save("useHostCores", &x.useHostCores) - m.Save("extraAuxv", &x.extraAuxv) - m.Save("vdso", &x.vdso) - m.Save("rootUTSNamespace", &x.rootUTSNamespace) - m.Save("rootIPCNamespace", &x.rootIPCNamespace) - m.Save("rootAbstractSocketNamespace", &x.rootAbstractSocketNamespace) - m.Save("futexes", &x.futexes) - m.Save("globalInit", &x.globalInit) - m.Save("realtimeClock", &x.realtimeClock) - m.Save("monotonicClock", &x.monotonicClock) - m.Save("syslog", &x.syslog) - m.Save("runningTasks", &x.runningTasks) - m.Save("cpuClock", &x.cpuClock) - m.Save("cpuClockTickerDisabled", &x.cpuClockTickerDisabled) - m.Save("cpuClockTickerSetting", &x.cpuClockTickerSetting) - m.Save("uniqueID", &x.uniqueID) - m.Save("nextInotifyCookie", &x.nextInotifyCookie) - m.Save("netlinkPorts", &x.netlinkPorts) - m.Save("sockets", &x.sockets) - m.Save("nextSocketEntry", &x.nextSocketEntry) - m.Save("DirentCacheLimiter", &x.DirentCacheLimiter) - m.Save("SpecialOpts", &x.SpecialOpts) - m.Save("vfs", &x.vfs) - m.Save("hostMount", &x.hostMount) - m.Save("pipeMount", &x.pipeMount) - m.Save("shmMount", &x.shmMount) - m.Save("socketMount", &x.socketMount) - m.Save("SleepForAddressSpaceActivation", &x.SleepForAddressSpaceActivation) + m.SaveValue(27, deviceRegistry) + m.Save(0, &x.featureSet) + m.Save(1, &x.timekeeper) + m.Save(2, &x.tasks) + m.Save(3, &x.rootUserNamespace) + m.Save(4, &x.rootNetworkNamespace) + m.Save(5, &x.applicationCores) + m.Save(6, &x.useHostCores) + m.Save(7, &x.extraAuxv) + m.Save(8, &x.vdso) + m.Save(9, &x.rootUTSNamespace) + m.Save(10, &x.rootIPCNamespace) + m.Save(11, &x.rootAbstractSocketNamespace) + m.Save(12, &x.futexes) + m.Save(13, &x.globalInit) + m.Save(14, &x.realtimeClock) + m.Save(15, &x.monotonicClock) + m.Save(16, &x.syslog) + m.Save(17, &x.runningTasks) + m.Save(18, &x.cpuClock) + m.Save(19, &x.cpuClockTickerDisabled) + m.Save(20, &x.cpuClockTickerSetting) + m.Save(21, &x.uniqueID) + m.Save(22, &x.nextInotifyCookie) + m.Save(23, &x.netlinkPorts) + m.Save(25, &x.sockets) + m.Save(26, &x.nextSocketEntry) + m.Save(28, &x.DirentCacheLimiter) + m.Save(29, &x.SpecialOpts) + m.Save(30, &x.vfs) + m.Save(31, &x.hostMount) + m.Save(32, &x.pipeMount) + m.Save(33, &x.shmMount) + m.Save(34, &x.socketMount) + m.Save(35, &x.SleepForAddressSpaceActivation) } func (x *Kernel) afterLoad() {} -func (x *Kernel) load(m state.Map) { - m.Load("featureSet", &x.featureSet) - m.Load("timekeeper", &x.timekeeper) - m.Load("tasks", &x.tasks) - m.Load("rootUserNamespace", &x.rootUserNamespace) - m.Load("rootNetworkNamespace", &x.rootNetworkNamespace) - m.Load("applicationCores", &x.applicationCores) - m.Load("useHostCores", &x.useHostCores) - m.Load("extraAuxv", &x.extraAuxv) - m.Load("vdso", &x.vdso) - m.Load("rootUTSNamespace", &x.rootUTSNamespace) - m.Load("rootIPCNamespace", &x.rootIPCNamespace) - m.Load("rootAbstractSocketNamespace", &x.rootAbstractSocketNamespace) - m.Load("futexes", &x.futexes) - m.Load("globalInit", &x.globalInit) - m.Load("realtimeClock", &x.realtimeClock) - m.Load("monotonicClock", &x.monotonicClock) - m.Load("syslog", &x.syslog) - m.Load("runningTasks", &x.runningTasks) - m.Load("cpuClock", &x.cpuClock) - m.Load("cpuClockTickerDisabled", &x.cpuClockTickerDisabled) - m.Load("cpuClockTickerSetting", &x.cpuClockTickerSetting) - m.Load("uniqueID", &x.uniqueID) - m.Load("nextInotifyCookie", &x.nextInotifyCookie) - m.Load("netlinkPorts", &x.netlinkPorts) - m.Load("sockets", &x.sockets) - m.Load("nextSocketEntry", &x.nextSocketEntry) - m.Load("DirentCacheLimiter", &x.DirentCacheLimiter) - m.Load("SpecialOpts", &x.SpecialOpts) - m.Load("vfs", &x.vfs) - m.Load("hostMount", &x.hostMount) - m.Load("pipeMount", &x.pipeMount) - m.Load("shmMount", &x.shmMount) - m.Load("socketMount", &x.socketMount) - m.Load("SleepForAddressSpaceActivation", &x.SleepForAddressSpaceActivation) - m.LoadValue("danglingEndpoints", new([]tcpip.Endpoint), func(y interface{}) { x.loadDanglingEndpoints(y.([]tcpip.Endpoint)) }) - m.LoadValue("deviceRegistry", new(*device.Registry), func(y interface{}) { x.loadDeviceRegistry(y.(*device.Registry)) }) + +func (x *Kernel) StateLoad(m state.Source) { + m.Load(0, &x.featureSet) + m.Load(1, &x.timekeeper) + m.Load(2, &x.tasks) + m.Load(3, &x.rootUserNamespace) + m.Load(4, &x.rootNetworkNamespace) + m.Load(5, &x.applicationCores) + m.Load(6, &x.useHostCores) + m.Load(7, &x.extraAuxv) + m.Load(8, &x.vdso) + m.Load(9, &x.rootUTSNamespace) + m.Load(10, &x.rootIPCNamespace) + m.Load(11, &x.rootAbstractSocketNamespace) + m.Load(12, &x.futexes) + m.Load(13, &x.globalInit) + m.Load(14, &x.realtimeClock) + m.Load(15, &x.monotonicClock) + m.Load(16, &x.syslog) + m.Load(17, &x.runningTasks) + m.Load(18, &x.cpuClock) + m.Load(19, &x.cpuClockTickerDisabled) + m.Load(20, &x.cpuClockTickerSetting) + m.Load(21, &x.uniqueID) + m.Load(22, &x.nextInotifyCookie) + m.Load(23, &x.netlinkPorts) + m.Load(25, &x.sockets) + m.Load(26, &x.nextSocketEntry) + m.Load(28, &x.DirentCacheLimiter) + m.Load(29, &x.SpecialOpts) + m.Load(30, &x.vfs) + m.Load(31, &x.hostMount) + m.Load(32, &x.pipeMount) + m.Load(33, &x.shmMount) + m.Load(34, &x.socketMount) + m.Load(35, &x.SleepForAddressSpaceActivation) + m.LoadValue(24, new([]tcpip.Endpoint), func(y interface{}) { x.loadDanglingEndpoints(y.([]tcpip.Endpoint)) }) + m.LoadValue(27, new(*device.Registry), func(y interface{}) { x.loadDeviceRegistry(y.(*device.Registry)) }) +} + +func (x *SocketEntry) StateTypeName() string { + return "pkg/sentry/kernel.SocketEntry" +} + +func (x *SocketEntry) StateFields() []string { + return []string{ + "socketEntry", + "k", + "Sock", + "SockVFS2", + "ID", + } } func (x *SocketEntry) beforeSave() {} -func (x *SocketEntry) save(m state.Map) { + +func (x *SocketEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("socketEntry", &x.socketEntry) - m.Save("k", &x.k) - m.Save("Sock", &x.Sock) - m.Save("SockVFS2", &x.SockVFS2) - m.Save("ID", &x.ID) + m.Save(0, &x.socketEntry) + m.Save(1, &x.k) + m.Save(2, &x.Sock) + m.Save(3, &x.SockVFS2) + m.Save(4, &x.ID) } func (x *SocketEntry) afterLoad() {} -func (x *SocketEntry) load(m state.Map) { - m.Load("socketEntry", &x.socketEntry) - m.Load("k", &x.k) - m.Load("Sock", &x.Sock) - m.Load("SockVFS2", &x.SockVFS2) - m.Load("ID", &x.ID) + +func (x *SocketEntry) StateLoad(m state.Source) { + m.Load(0, &x.socketEntry) + m.Load(1, &x.k) + m.Load(2, &x.Sock) + m.Load(3, &x.SockVFS2) + m.Load(4, &x.ID) +} + +func (x *pendingSignals) StateTypeName() string { + return "pkg/sentry/kernel.pendingSignals" +} + +func (x *pendingSignals) StateFields() []string { + return []string{ + "signals", + } } func (x *pendingSignals) beforeSave() {} -func (x *pendingSignals) save(m state.Map) { + +func (x *pendingSignals) StateSave(m state.Sink) { x.beforeSave() var signals []savedPendingSignal = x.saveSignals() - m.SaveValue("signals", signals) + m.SaveValue(0, signals) } func (x *pendingSignals) afterLoad() {} -func (x *pendingSignals) load(m state.Map) { - m.LoadValue("signals", new([]savedPendingSignal), func(y interface{}) { x.loadSignals(y.([]savedPendingSignal)) }) + +func (x *pendingSignals) StateLoad(m state.Source) { + m.LoadValue(0, new([]savedPendingSignal), func(y interface{}) { x.loadSignals(y.([]savedPendingSignal)) }) +} + +func (x *pendingSignalQueue) StateTypeName() string { + return "pkg/sentry/kernel.pendingSignalQueue" +} + +func (x *pendingSignalQueue) StateFields() []string { + return []string{ + "pendingSignalList", + "length", + } } func (x *pendingSignalQueue) beforeSave() {} -func (x *pendingSignalQueue) save(m state.Map) { + +func (x *pendingSignalQueue) StateSave(m state.Sink) { x.beforeSave() - m.Save("pendingSignalList", &x.pendingSignalList) - m.Save("length", &x.length) + m.Save(0, &x.pendingSignalList) + m.Save(1, &x.length) } func (x *pendingSignalQueue) afterLoad() {} -func (x *pendingSignalQueue) load(m state.Map) { - m.Load("pendingSignalList", &x.pendingSignalList) - m.Load("length", &x.length) + +func (x *pendingSignalQueue) StateLoad(m state.Source) { + m.Load(0, &x.pendingSignalList) + m.Load(1, &x.length) +} + +func (x *pendingSignal) StateTypeName() string { + return "pkg/sentry/kernel.pendingSignal" +} + +func (x *pendingSignal) StateFields() []string { + return []string{ + "pendingSignalEntry", + "SignalInfo", + "timer", + } } func (x *pendingSignal) beforeSave() {} -func (x *pendingSignal) save(m state.Map) { + +func (x *pendingSignal) StateSave(m state.Sink) { x.beforeSave() - m.Save("pendingSignalEntry", &x.pendingSignalEntry) - m.Save("SignalInfo", &x.SignalInfo) - m.Save("timer", &x.timer) + m.Save(0, &x.pendingSignalEntry) + m.Save(1, &x.SignalInfo) + m.Save(2, &x.timer) } func (x *pendingSignal) afterLoad() {} -func (x *pendingSignal) load(m state.Map) { - m.Load("pendingSignalEntry", &x.pendingSignalEntry) - m.Load("SignalInfo", &x.SignalInfo) - m.Load("timer", &x.timer) + +func (x *pendingSignal) StateLoad(m state.Source) { + m.Load(0, &x.pendingSignalEntry) + m.Load(1, &x.SignalInfo) + m.Load(2, &x.timer) +} + +func (x *pendingSignalList) StateTypeName() string { + return "pkg/sentry/kernel.pendingSignalList" +} + +func (x *pendingSignalList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *pendingSignalList) beforeSave() {} -func (x *pendingSignalList) save(m state.Map) { + +func (x *pendingSignalList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *pendingSignalList) afterLoad() {} -func (x *pendingSignalList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *pendingSignalList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *pendingSignalEntry) StateTypeName() string { + return "pkg/sentry/kernel.pendingSignalEntry" +} + +func (x *pendingSignalEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *pendingSignalEntry) beforeSave() {} -func (x *pendingSignalEntry) save(m state.Map) { + +func (x *pendingSignalEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *pendingSignalEntry) afterLoad() {} -func (x *pendingSignalEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *pendingSignalEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) +} + +func (x *savedPendingSignal) StateTypeName() string { + return "pkg/sentry/kernel.savedPendingSignal" +} + +func (x *savedPendingSignal) StateFields() []string { + return []string{ + "si", + "timer", + } } func (x *savedPendingSignal) beforeSave() {} -func (x *savedPendingSignal) save(m state.Map) { + +func (x *savedPendingSignal) StateSave(m state.Sink) { x.beforeSave() - m.Save("si", &x.si) - m.Save("timer", &x.timer) + m.Save(0, &x.si) + m.Save(1, &x.timer) } func (x *savedPendingSignal) afterLoad() {} -func (x *savedPendingSignal) load(m state.Map) { - m.Load("si", &x.si) - m.Load("timer", &x.timer) + +func (x *savedPendingSignal) StateLoad(m state.Source) { + m.Load(0, &x.si) + m.Load(1, &x.timer) +} + +func (x *IntervalTimer) StateTypeName() string { + return "pkg/sentry/kernel.IntervalTimer" +} + +func (x *IntervalTimer) StateFields() []string { + return []string{ + "timer", + "target", + "signo", + "id", + "sigval", + "group", + "sigpending", + "sigorphan", + "overrunCur", + "overrunLast", + } } func (x *IntervalTimer) beforeSave() {} -func (x *IntervalTimer) save(m state.Map) { + +func (x *IntervalTimer) StateSave(m state.Sink) { x.beforeSave() - m.Save("timer", &x.timer) - m.Save("target", &x.target) - m.Save("signo", &x.signo) - m.Save("id", &x.id) - m.Save("sigval", &x.sigval) - m.Save("group", &x.group) - m.Save("sigpending", &x.sigpending) - m.Save("sigorphan", &x.sigorphan) - m.Save("overrunCur", &x.overrunCur) - m.Save("overrunLast", &x.overrunLast) + m.Save(0, &x.timer) + m.Save(1, &x.target) + m.Save(2, &x.signo) + m.Save(3, &x.id) + m.Save(4, &x.sigval) + m.Save(5, &x.group) + m.Save(6, &x.sigpending) + m.Save(7, &x.sigorphan) + m.Save(8, &x.overrunCur) + m.Save(9, &x.overrunLast) } func (x *IntervalTimer) afterLoad() {} -func (x *IntervalTimer) load(m state.Map) { - m.Load("timer", &x.timer) - m.Load("target", &x.target) - m.Load("signo", &x.signo) - m.Load("id", &x.id) - m.Load("sigval", &x.sigval) - m.Load("group", &x.group) - m.Load("sigpending", &x.sigpending) - m.Load("sigorphan", &x.sigorphan) - m.Load("overrunCur", &x.overrunCur) - m.Load("overrunLast", &x.overrunLast) + +func (x *IntervalTimer) StateLoad(m state.Source) { + m.Load(0, &x.timer) + m.Load(1, &x.target) + m.Load(2, &x.signo) + m.Load(3, &x.id) + m.Load(4, &x.sigval) + m.Load(5, &x.group) + m.Load(6, &x.sigpending) + m.Load(7, &x.sigorphan) + m.Load(8, &x.overrunCur) + m.Load(9, &x.overrunLast) +} + +func (x *processGroupList) StateTypeName() string { + return "pkg/sentry/kernel.processGroupList" +} + +func (x *processGroupList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *processGroupList) beforeSave() {} -func (x *processGroupList) save(m state.Map) { + +func (x *processGroupList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *processGroupList) afterLoad() {} -func (x *processGroupList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *processGroupList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *processGroupEntry) StateTypeName() string { + return "pkg/sentry/kernel.processGroupEntry" +} + +func (x *processGroupEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *processGroupEntry) beforeSave() {} -func (x *processGroupEntry) save(m state.Map) { + +func (x *processGroupEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *processGroupEntry) afterLoad() {} -func (x *processGroupEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *processGroupEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) +} + +func (x *ptraceOptions) StateTypeName() string { + return "pkg/sentry/kernel.ptraceOptions" +} + +func (x *ptraceOptions) StateFields() []string { + return []string{ + "ExitKill", + "SysGood", + "TraceClone", + "TraceExec", + "TraceExit", + "TraceFork", + "TraceSeccomp", + "TraceVfork", + "TraceVforkDone", + } } func (x *ptraceOptions) beforeSave() {} -func (x *ptraceOptions) save(m state.Map) { + +func (x *ptraceOptions) StateSave(m state.Sink) { x.beforeSave() - m.Save("ExitKill", &x.ExitKill) - m.Save("SysGood", &x.SysGood) - m.Save("TraceClone", &x.TraceClone) - m.Save("TraceExec", &x.TraceExec) - m.Save("TraceExit", &x.TraceExit) - m.Save("TraceFork", &x.TraceFork) - m.Save("TraceSeccomp", &x.TraceSeccomp) - m.Save("TraceVfork", &x.TraceVfork) - m.Save("TraceVforkDone", &x.TraceVforkDone) + m.Save(0, &x.ExitKill) + m.Save(1, &x.SysGood) + m.Save(2, &x.TraceClone) + m.Save(3, &x.TraceExec) + m.Save(4, &x.TraceExit) + m.Save(5, &x.TraceFork) + m.Save(6, &x.TraceSeccomp) + m.Save(7, &x.TraceVfork) + m.Save(8, &x.TraceVforkDone) } func (x *ptraceOptions) afterLoad() {} -func (x *ptraceOptions) load(m state.Map) { - m.Load("ExitKill", &x.ExitKill) - m.Load("SysGood", &x.SysGood) - m.Load("TraceClone", &x.TraceClone) - m.Load("TraceExec", &x.TraceExec) - m.Load("TraceExit", &x.TraceExit) - m.Load("TraceFork", &x.TraceFork) - m.Load("TraceSeccomp", &x.TraceSeccomp) - m.Load("TraceVfork", &x.TraceVfork) - m.Load("TraceVforkDone", &x.TraceVforkDone) + +func (x *ptraceOptions) StateLoad(m state.Source) { + m.Load(0, &x.ExitKill) + m.Load(1, &x.SysGood) + m.Load(2, &x.TraceClone) + m.Load(3, &x.TraceExec) + m.Load(4, &x.TraceExit) + m.Load(5, &x.TraceFork) + m.Load(6, &x.TraceSeccomp) + m.Load(7, &x.TraceVfork) + m.Load(8, &x.TraceVforkDone) +} + +func (x *ptraceStop) StateTypeName() string { + return "pkg/sentry/kernel.ptraceStop" +} + +func (x *ptraceStop) StateFields() []string { + return []string{ + "frozen", + "listen", + } } func (x *ptraceStop) beforeSave() {} -func (x *ptraceStop) save(m state.Map) { + +func (x *ptraceStop) StateSave(m state.Sink) { x.beforeSave() - m.Save("frozen", &x.frozen) - m.Save("listen", &x.listen) + m.Save(0, &x.frozen) + m.Save(1, &x.listen) } func (x *ptraceStop) afterLoad() {} -func (x *ptraceStop) load(m state.Map) { - m.Load("frozen", &x.frozen) - m.Load("listen", &x.listen) + +func (x *ptraceStop) StateLoad(m state.Source) { + m.Load(0, &x.frozen) + m.Load(1, &x.listen) +} + +func (x *OldRSeqCriticalRegion) StateTypeName() string { + return "pkg/sentry/kernel.OldRSeqCriticalRegion" +} + +func (x *OldRSeqCriticalRegion) StateFields() []string { + return []string{ + "CriticalSection", + "Restart", + } } func (x *OldRSeqCriticalRegion) beforeSave() {} -func (x *OldRSeqCriticalRegion) save(m state.Map) { + +func (x *OldRSeqCriticalRegion) StateSave(m state.Sink) { x.beforeSave() - m.Save("CriticalSection", &x.CriticalSection) - m.Save("Restart", &x.Restart) + m.Save(0, &x.CriticalSection) + m.Save(1, &x.Restart) } func (x *OldRSeqCriticalRegion) afterLoad() {} -func (x *OldRSeqCriticalRegion) load(m state.Map) { - m.Load("CriticalSection", &x.CriticalSection) - m.Load("Restart", &x.Restart) + +func (x *OldRSeqCriticalRegion) StateLoad(m state.Source) { + m.Load(0, &x.CriticalSection) + m.Load(1, &x.Restart) +} + +func (x *sessionList) StateTypeName() string { + return "pkg/sentry/kernel.sessionList" +} + +func (x *sessionList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *sessionList) beforeSave() {} -func (x *sessionList) save(m state.Map) { + +func (x *sessionList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *sessionList) afterLoad() {} -func (x *sessionList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *sessionList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *sessionEntry) StateTypeName() string { + return "pkg/sentry/kernel.sessionEntry" +} + +func (x *sessionEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *sessionEntry) beforeSave() {} -func (x *sessionEntry) save(m state.Map) { + +func (x *sessionEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *sessionEntry) afterLoad() {} -func (x *sessionEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *sessionEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) +} + +func (x *Session) StateTypeName() string { + return "pkg/sentry/kernel.Session" +} + +func (x *Session) StateFields() []string { + return []string{ + "refs", + "leader", + "id", + "foreground", + "processGroups", + "sessionEntry", + } } func (x *Session) beforeSave() {} -func (x *Session) save(m state.Map) { + +func (x *Session) StateSave(m state.Sink) { x.beforeSave() - m.Save("refs", &x.refs) - m.Save("leader", &x.leader) - m.Save("id", &x.id) - m.Save("foreground", &x.foreground) - m.Save("processGroups", &x.processGroups) - m.Save("sessionEntry", &x.sessionEntry) + m.Save(0, &x.refs) + m.Save(1, &x.leader) + m.Save(2, &x.id) + m.Save(3, &x.foreground) + m.Save(4, &x.processGroups) + m.Save(5, &x.sessionEntry) } func (x *Session) afterLoad() {} -func (x *Session) load(m state.Map) { - m.Load("refs", &x.refs) - m.Load("leader", &x.leader) - m.Load("id", &x.id) - m.Load("foreground", &x.foreground) - m.Load("processGroups", &x.processGroups) - m.Load("sessionEntry", &x.sessionEntry) + +func (x *Session) StateLoad(m state.Source) { + m.Load(0, &x.refs) + m.Load(1, &x.leader) + m.Load(2, &x.id) + m.Load(3, &x.foreground) + m.Load(4, &x.processGroups) + m.Load(5, &x.sessionEntry) +} + +func (x *ProcessGroup) StateTypeName() string { + return "pkg/sentry/kernel.ProcessGroup" +} + +func (x *ProcessGroup) StateFields() []string { + return []string{ + "refs", + "originator", + "id", + "session", + "ancestors", + "processGroupEntry", + } } func (x *ProcessGroup) beforeSave() {} -func (x *ProcessGroup) save(m state.Map) { + +func (x *ProcessGroup) StateSave(m state.Sink) { x.beforeSave() - m.Save("refs", &x.refs) - m.Save("originator", &x.originator) - m.Save("id", &x.id) - m.Save("session", &x.session) - m.Save("ancestors", &x.ancestors) - m.Save("processGroupEntry", &x.processGroupEntry) + m.Save(0, &x.refs) + m.Save(1, &x.originator) + m.Save(2, &x.id) + m.Save(3, &x.session) + m.Save(4, &x.ancestors) + m.Save(5, &x.processGroupEntry) } func (x *ProcessGroup) afterLoad() {} -func (x *ProcessGroup) load(m state.Map) { - m.Load("refs", &x.refs) - m.Load("originator", &x.originator) - m.Load("id", &x.id) - m.Load("session", &x.session) - m.Load("ancestors", &x.ancestors) - m.Load("processGroupEntry", &x.processGroupEntry) + +func (x *ProcessGroup) StateLoad(m state.Source) { + m.Load(0, &x.refs) + m.Load(1, &x.originator) + m.Load(2, &x.id) + m.Load(3, &x.session) + m.Load(4, &x.ancestors) + m.Load(5, &x.processGroupEntry) +} + +func (x *SignalHandlers) StateTypeName() string { + return "pkg/sentry/kernel.SignalHandlers" +} + +func (x *SignalHandlers) StateFields() []string { + return []string{ + "actions", + } } func (x *SignalHandlers) beforeSave() {} -func (x *SignalHandlers) save(m state.Map) { + +func (x *SignalHandlers) StateSave(m state.Sink) { x.beforeSave() - m.Save("actions", &x.actions) + m.Save(0, &x.actions) } func (x *SignalHandlers) afterLoad() {} -func (x *SignalHandlers) load(m state.Map) { - m.Load("actions", &x.actions) + +func (x *SignalHandlers) StateLoad(m state.Source) { + m.Load(0, &x.actions) +} + +func (x *socketList) StateTypeName() string { + return "pkg/sentry/kernel.socketList" +} + +func (x *socketList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *socketList) beforeSave() {} -func (x *socketList) save(m state.Map) { + +func (x *socketList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *socketList) afterLoad() {} -func (x *socketList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *socketList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *socketEntry) StateTypeName() string { + return "pkg/sentry/kernel.socketEntry" +} + +func (x *socketEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *socketEntry) beforeSave() {} -func (x *socketEntry) save(m state.Map) { + +func (x *socketEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *socketEntry) afterLoad() {} -func (x *socketEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *socketEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) +} + +func (x *syscallTableInfo) StateTypeName() string { + return "pkg/sentry/kernel.syscallTableInfo" +} + +func (x *syscallTableInfo) StateFields() []string { + return []string{ + "OS", + "Arch", + } } func (x *syscallTableInfo) beforeSave() {} -func (x *syscallTableInfo) save(m state.Map) { + +func (x *syscallTableInfo) StateSave(m state.Sink) { x.beforeSave() - m.Save("OS", &x.OS) - m.Save("Arch", &x.Arch) + m.Save(0, &x.OS) + m.Save(1, &x.Arch) } func (x *syscallTableInfo) afterLoad() {} -func (x *syscallTableInfo) load(m state.Map) { - m.Load("OS", &x.OS) - m.Load("Arch", &x.Arch) + +func (x *syscallTableInfo) StateLoad(m state.Source) { + m.Load(0, &x.OS) + m.Load(1, &x.Arch) +} + +func (x *syslog) StateTypeName() string { + return "pkg/sentry/kernel.syslog" +} + +func (x *syslog) StateFields() []string { + return []string{ + "msg", + } } func (x *syslog) beforeSave() {} -func (x *syslog) save(m state.Map) { + +func (x *syslog) StateSave(m state.Sink) { x.beforeSave() - m.Save("msg", &x.msg) + m.Save(0, &x.msg) } func (x *syslog) afterLoad() {} -func (x *syslog) load(m state.Map) { - m.Load("msg", &x.msg) + +func (x *syslog) StateLoad(m state.Source) { + m.Load(0, &x.msg) +} + +func (x *Task) StateTypeName() string { + return "pkg/sentry/kernel.Task" +} + +func (x *Task) StateFields() []string { + return []string{ + "taskNode", + "runState", + "haveSyscallReturn", + "gosched", + "yieldCount", + "pendingSignals", + "signalMask", + "realSignalMask", + "haveSavedSignalMask", + "savedSignalMask", + "signalStack", + "groupStopPending", + "groupStopAcknowledged", + "trapStopPending", + "trapNotifyPending", + "stop", + "exitStatus", + "syscallRestartBlock", + "k", + "containerID", + "tc", + "fsContext", + "fdTable", + "vforkParent", + "exitState", + "exitTracerNotified", + "exitTracerAcked", + "exitParentNotified", + "exitParentAcked", + "ptraceTracer", + "ptraceTracees", + "ptraceSeized", + "ptraceOpts", + "ptraceSyscallMode", + "ptraceSinglestep", + "ptraceCode", + "ptraceSiginfo", + "ptraceEventMsg", + "ioUsage", + "creds", + "utsns", + "ipcns", + "abstractSockets", + "mountNamespaceVFS2", + "parentDeathSignal", + "syscallFilters", + "cleartid", + "allowedCPUMask", + "cpu", + "niceness", + "numaPolicy", + "numaNodeMask", + "netns", + "rseqCPU", + "oldRSeqCPUAddr", + "rseqAddr", + "rseqSignature", + "startTime", + } } func (x *Task) beforeSave() {} -func (x *Task) save(m state.Map) { + +func (x *Task) StateSave(m state.Sink) { x.beforeSave() if !state.IsZeroValue(&x.signalQueue) { - m.Failf("signalQueue is %#v, expected zero", &x.signalQueue) + state.Failf("signalQueue is %#v, expected zero", &x.signalQueue) } var ptraceTracer *Task = x.savePtraceTracer() - m.SaveValue("ptraceTracer", ptraceTracer) + m.SaveValue(29, ptraceTracer) var syscallFilters []bpf.Program = x.saveSyscallFilters() - m.SaveValue("syscallFilters", syscallFilters) - m.Save("taskNode", &x.taskNode) - m.Save("runState", &x.runState) - m.Save("haveSyscallReturn", &x.haveSyscallReturn) - m.Save("gosched", &x.gosched) - m.Save("yieldCount", &x.yieldCount) - m.Save("pendingSignals", &x.pendingSignals) - m.Save("signalMask", &x.signalMask) - m.Save("realSignalMask", &x.realSignalMask) - m.Save("haveSavedSignalMask", &x.haveSavedSignalMask) - m.Save("savedSignalMask", &x.savedSignalMask) - m.Save("signalStack", &x.signalStack) - m.Save("groupStopPending", &x.groupStopPending) - m.Save("groupStopAcknowledged", &x.groupStopAcknowledged) - m.Save("trapStopPending", &x.trapStopPending) - m.Save("trapNotifyPending", &x.trapNotifyPending) - m.Save("stop", &x.stop) - m.Save("exitStatus", &x.exitStatus) - m.Save("syscallRestartBlock", &x.syscallRestartBlock) - m.Save("k", &x.k) - m.Save("containerID", &x.containerID) - m.Save("tc", &x.tc) - m.Save("fsContext", &x.fsContext) - m.Save("fdTable", &x.fdTable) - m.Save("vforkParent", &x.vforkParent) - m.Save("exitState", &x.exitState) - m.Save("exitTracerNotified", &x.exitTracerNotified) - m.Save("exitTracerAcked", &x.exitTracerAcked) - m.Save("exitParentNotified", &x.exitParentNotified) - m.Save("exitParentAcked", &x.exitParentAcked) - m.Save("ptraceTracees", &x.ptraceTracees) - m.Save("ptraceSeized", &x.ptraceSeized) - m.Save("ptraceOpts", &x.ptraceOpts) - m.Save("ptraceSyscallMode", &x.ptraceSyscallMode) - m.Save("ptraceSinglestep", &x.ptraceSinglestep) - m.Save("ptraceCode", &x.ptraceCode) - m.Save("ptraceSiginfo", &x.ptraceSiginfo) - m.Save("ptraceEventMsg", &x.ptraceEventMsg) - m.Save("ioUsage", &x.ioUsage) - m.Save("creds", &x.creds) - m.Save("utsns", &x.utsns) - m.Save("ipcns", &x.ipcns) - m.Save("abstractSockets", &x.abstractSockets) - m.Save("mountNamespaceVFS2", &x.mountNamespaceVFS2) - m.Save("parentDeathSignal", &x.parentDeathSignal) - m.Save("cleartid", &x.cleartid) - m.Save("allowedCPUMask", &x.allowedCPUMask) - m.Save("cpu", &x.cpu) - m.Save("niceness", &x.niceness) - m.Save("numaPolicy", &x.numaPolicy) - m.Save("numaNodeMask", &x.numaNodeMask) - m.Save("netns", &x.netns) - m.Save("rseqCPU", &x.rseqCPU) - m.Save("oldRSeqCPUAddr", &x.oldRSeqCPUAddr) - m.Save("rseqAddr", &x.rseqAddr) - m.Save("rseqSignature", &x.rseqSignature) - m.Save("startTime", &x.startTime) -} - -func (x *Task) load(m state.Map) { - m.Load("taskNode", &x.taskNode) - m.Load("runState", &x.runState) - m.Load("haveSyscallReturn", &x.haveSyscallReturn) - m.Load("gosched", &x.gosched) - m.Load("yieldCount", &x.yieldCount) - m.Load("pendingSignals", &x.pendingSignals) - m.Load("signalMask", &x.signalMask) - m.Load("realSignalMask", &x.realSignalMask) - m.Load("haveSavedSignalMask", &x.haveSavedSignalMask) - m.Load("savedSignalMask", &x.savedSignalMask) - m.Load("signalStack", &x.signalStack) - m.Load("groupStopPending", &x.groupStopPending) - m.Load("groupStopAcknowledged", &x.groupStopAcknowledged) - m.Load("trapStopPending", &x.trapStopPending) - m.Load("trapNotifyPending", &x.trapNotifyPending) - m.Load("stop", &x.stop) - m.Load("exitStatus", &x.exitStatus) - m.Load("syscallRestartBlock", &x.syscallRestartBlock) - m.Load("k", &x.k) - m.Load("containerID", &x.containerID) - m.Load("tc", &x.tc) - m.Load("fsContext", &x.fsContext) - m.Load("fdTable", &x.fdTable) - m.Load("vforkParent", &x.vforkParent) - m.Load("exitState", &x.exitState) - m.Load("exitTracerNotified", &x.exitTracerNotified) - m.Load("exitTracerAcked", &x.exitTracerAcked) - m.Load("exitParentNotified", &x.exitParentNotified) - m.Load("exitParentAcked", &x.exitParentAcked) - m.Load("ptraceTracees", &x.ptraceTracees) - m.Load("ptraceSeized", &x.ptraceSeized) - m.Load("ptraceOpts", &x.ptraceOpts) - m.Load("ptraceSyscallMode", &x.ptraceSyscallMode) - m.Load("ptraceSinglestep", &x.ptraceSinglestep) - m.Load("ptraceCode", &x.ptraceCode) - m.Load("ptraceSiginfo", &x.ptraceSiginfo) - m.Load("ptraceEventMsg", &x.ptraceEventMsg) - m.Load("ioUsage", &x.ioUsage) - m.Load("creds", &x.creds) - m.Load("utsns", &x.utsns) - m.Load("ipcns", &x.ipcns) - m.Load("abstractSockets", &x.abstractSockets) - m.Load("mountNamespaceVFS2", &x.mountNamespaceVFS2) - m.Load("parentDeathSignal", &x.parentDeathSignal) - m.Load("cleartid", &x.cleartid) - m.Load("allowedCPUMask", &x.allowedCPUMask) - m.Load("cpu", &x.cpu) - m.Load("niceness", &x.niceness) - m.Load("numaPolicy", &x.numaPolicy) - m.Load("numaNodeMask", &x.numaNodeMask) - m.Load("netns", &x.netns) - m.Load("rseqCPU", &x.rseqCPU) - m.Load("oldRSeqCPUAddr", &x.oldRSeqCPUAddr) - m.Load("rseqAddr", &x.rseqAddr) - m.Load("rseqSignature", &x.rseqSignature) - m.Load("startTime", &x.startTime) - m.LoadValue("ptraceTracer", new(*Task), func(y interface{}) { x.loadPtraceTracer(y.(*Task)) }) - m.LoadValue("syscallFilters", new([]bpf.Program), func(y interface{}) { x.loadSyscallFilters(y.([]bpf.Program)) }) + m.SaveValue(45, syscallFilters) + m.Save(0, &x.taskNode) + m.Save(1, &x.runState) + m.Save(2, &x.haveSyscallReturn) + m.Save(3, &x.gosched) + m.Save(4, &x.yieldCount) + m.Save(5, &x.pendingSignals) + m.Save(6, &x.signalMask) + m.Save(7, &x.realSignalMask) + m.Save(8, &x.haveSavedSignalMask) + m.Save(9, &x.savedSignalMask) + m.Save(10, &x.signalStack) + m.Save(11, &x.groupStopPending) + m.Save(12, &x.groupStopAcknowledged) + m.Save(13, &x.trapStopPending) + m.Save(14, &x.trapNotifyPending) + m.Save(15, &x.stop) + m.Save(16, &x.exitStatus) + m.Save(17, &x.syscallRestartBlock) + m.Save(18, &x.k) + m.Save(19, &x.containerID) + m.Save(20, &x.tc) + m.Save(21, &x.fsContext) + m.Save(22, &x.fdTable) + m.Save(23, &x.vforkParent) + m.Save(24, &x.exitState) + m.Save(25, &x.exitTracerNotified) + m.Save(26, &x.exitTracerAcked) + m.Save(27, &x.exitParentNotified) + m.Save(28, &x.exitParentAcked) + m.Save(30, &x.ptraceTracees) + m.Save(31, &x.ptraceSeized) + m.Save(32, &x.ptraceOpts) + m.Save(33, &x.ptraceSyscallMode) + m.Save(34, &x.ptraceSinglestep) + m.Save(35, &x.ptraceCode) + m.Save(36, &x.ptraceSiginfo) + m.Save(37, &x.ptraceEventMsg) + m.Save(38, &x.ioUsage) + m.Save(39, &x.creds) + m.Save(40, &x.utsns) + m.Save(41, &x.ipcns) + m.Save(42, &x.abstractSockets) + m.Save(43, &x.mountNamespaceVFS2) + m.Save(44, &x.parentDeathSignal) + m.Save(46, &x.cleartid) + m.Save(47, &x.allowedCPUMask) + m.Save(48, &x.cpu) + m.Save(49, &x.niceness) + m.Save(50, &x.numaPolicy) + m.Save(51, &x.numaNodeMask) + m.Save(52, &x.netns) + m.Save(53, &x.rseqCPU) + m.Save(54, &x.oldRSeqCPUAddr) + m.Save(55, &x.rseqAddr) + m.Save(56, &x.rseqSignature) + m.Save(57, &x.startTime) +} + +func (x *Task) StateLoad(m state.Source) { + m.Load(0, &x.taskNode) + m.Load(1, &x.runState) + m.Load(2, &x.haveSyscallReturn) + m.Load(3, &x.gosched) + m.Load(4, &x.yieldCount) + m.Load(5, &x.pendingSignals) + m.Load(6, &x.signalMask) + m.Load(7, &x.realSignalMask) + m.Load(8, &x.haveSavedSignalMask) + m.Load(9, &x.savedSignalMask) + m.Load(10, &x.signalStack) + m.Load(11, &x.groupStopPending) + m.Load(12, &x.groupStopAcknowledged) + m.Load(13, &x.trapStopPending) + m.Load(14, &x.trapNotifyPending) + m.Load(15, &x.stop) + m.Load(16, &x.exitStatus) + m.Load(17, &x.syscallRestartBlock) + m.Load(18, &x.k) + m.Load(19, &x.containerID) + m.Load(20, &x.tc) + m.Load(21, &x.fsContext) + m.Load(22, &x.fdTable) + m.Load(23, &x.vforkParent) + m.Load(24, &x.exitState) + m.Load(25, &x.exitTracerNotified) + m.Load(26, &x.exitTracerAcked) + m.Load(27, &x.exitParentNotified) + m.Load(28, &x.exitParentAcked) + m.Load(30, &x.ptraceTracees) + m.Load(31, &x.ptraceSeized) + m.Load(32, &x.ptraceOpts) + m.Load(33, &x.ptraceSyscallMode) + m.Load(34, &x.ptraceSinglestep) + m.Load(35, &x.ptraceCode) + m.Load(36, &x.ptraceSiginfo) + m.Load(37, &x.ptraceEventMsg) + m.Load(38, &x.ioUsage) + m.Load(39, &x.creds) + m.Load(40, &x.utsns) + m.Load(41, &x.ipcns) + m.Load(42, &x.abstractSockets) + m.Load(43, &x.mountNamespaceVFS2) + m.Load(44, &x.parentDeathSignal) + m.Load(46, &x.cleartid) + m.Load(47, &x.allowedCPUMask) + m.Load(48, &x.cpu) + m.Load(49, &x.niceness) + m.Load(50, &x.numaPolicy) + m.Load(51, &x.numaNodeMask) + m.Load(52, &x.netns) + m.Load(53, &x.rseqCPU) + m.Load(54, &x.oldRSeqCPUAddr) + m.Load(55, &x.rseqAddr) + m.Load(56, &x.rseqSignature) + m.Load(57, &x.startTime) + m.LoadValue(29, new(*Task), func(y interface{}) { x.loadPtraceTracer(y.(*Task)) }) + m.LoadValue(45, new([]bpf.Program), func(y interface{}) { x.loadSyscallFilters(y.([]bpf.Program)) }) m.AfterLoad(x.afterLoad) } +func (x *runSyscallAfterPtraceEventClone) StateTypeName() string { + return "pkg/sentry/kernel.runSyscallAfterPtraceEventClone" +} + +func (x *runSyscallAfterPtraceEventClone) StateFields() []string { + return []string{ + "vforkChild", + "vforkChildTID", + } +} + func (x *runSyscallAfterPtraceEventClone) beforeSave() {} -func (x *runSyscallAfterPtraceEventClone) save(m state.Map) { + +func (x *runSyscallAfterPtraceEventClone) StateSave(m state.Sink) { x.beforeSave() - m.Save("vforkChild", &x.vforkChild) - m.Save("vforkChildTID", &x.vforkChildTID) + m.Save(0, &x.vforkChild) + m.Save(1, &x.vforkChildTID) } func (x *runSyscallAfterPtraceEventClone) afterLoad() {} -func (x *runSyscallAfterPtraceEventClone) load(m state.Map) { - m.Load("vforkChild", &x.vforkChild) - m.Load("vforkChildTID", &x.vforkChildTID) + +func (x *runSyscallAfterPtraceEventClone) StateLoad(m state.Source) { + m.Load(0, &x.vforkChild) + m.Load(1, &x.vforkChildTID) +} + +func (x *runSyscallAfterVforkStop) StateTypeName() string { + return "pkg/sentry/kernel.runSyscallAfterVforkStop" +} + +func (x *runSyscallAfterVforkStop) StateFields() []string { + return []string{ + "childTID", + } } func (x *runSyscallAfterVforkStop) beforeSave() {} -func (x *runSyscallAfterVforkStop) save(m state.Map) { + +func (x *runSyscallAfterVforkStop) StateSave(m state.Sink) { x.beforeSave() - m.Save("childTID", &x.childTID) + m.Save(0, &x.childTID) } func (x *runSyscallAfterVforkStop) afterLoad() {} -func (x *runSyscallAfterVforkStop) load(m state.Map) { - m.Load("childTID", &x.childTID) + +func (x *runSyscallAfterVforkStop) StateLoad(m state.Source) { + m.Load(0, &x.childTID) +} + +func (x *vforkStop) StateTypeName() string { + return "pkg/sentry/kernel.vforkStop" +} + +func (x *vforkStop) StateFields() []string { + return []string{} } func (x *vforkStop) beforeSave() {} -func (x *vforkStop) save(m state.Map) { + +func (x *vforkStop) StateSave(m state.Sink) { x.beforeSave() } func (x *vforkStop) afterLoad() {} -func (x *vforkStop) load(m state.Map) { + +func (x *vforkStop) StateLoad(m state.Source) { +} + +func (x *TaskContext) StateTypeName() string { + return "pkg/sentry/kernel.TaskContext" +} + +func (x *TaskContext) StateFields() []string { + return []string{ + "Name", + "Arch", + "MemoryManager", + "fu", + "st", + } } func (x *TaskContext) beforeSave() {} -func (x *TaskContext) save(m state.Map) { + +func (x *TaskContext) StateSave(m state.Sink) { x.beforeSave() var st syscallTableInfo = x.saveSt() - m.SaveValue("st", st) - m.Save("Name", &x.Name) - m.Save("Arch", &x.Arch) - m.Save("MemoryManager", &x.MemoryManager) - m.Save("fu", &x.fu) + m.SaveValue(4, st) + m.Save(0, &x.Name) + m.Save(1, &x.Arch) + m.Save(2, &x.MemoryManager) + m.Save(3, &x.fu) } func (x *TaskContext) afterLoad() {} -func (x *TaskContext) load(m state.Map) { - m.Load("Name", &x.Name) - m.Load("Arch", &x.Arch) - m.Load("MemoryManager", &x.MemoryManager) - m.Load("fu", &x.fu) - m.LoadValue("st", new(syscallTableInfo), func(y interface{}) { x.loadSt(y.(syscallTableInfo)) }) + +func (x *TaskContext) StateLoad(m state.Source) { + m.Load(0, &x.Name) + m.Load(1, &x.Arch) + m.Load(2, &x.MemoryManager) + m.Load(3, &x.fu) + m.LoadValue(4, new(syscallTableInfo), func(y interface{}) { x.loadSt(y.(syscallTableInfo)) }) +} + +func (x *execStop) StateTypeName() string { + return "pkg/sentry/kernel.execStop" +} + +func (x *execStop) StateFields() []string { + return []string{} } func (x *execStop) beforeSave() {} -func (x *execStop) save(m state.Map) { + +func (x *execStop) StateSave(m state.Sink) { x.beforeSave() } func (x *execStop) afterLoad() {} -func (x *execStop) load(m state.Map) { + +func (x *execStop) StateLoad(m state.Source) { +} + +func (x *runSyscallAfterExecStop) StateTypeName() string { + return "pkg/sentry/kernel.runSyscallAfterExecStop" +} + +func (x *runSyscallAfterExecStop) StateFields() []string { + return []string{ + "tc", + } } func (x *runSyscallAfterExecStop) beforeSave() {} -func (x *runSyscallAfterExecStop) save(m state.Map) { + +func (x *runSyscallAfterExecStop) StateSave(m state.Sink) { x.beforeSave() - m.Save("tc", &x.tc) + m.Save(0, &x.tc) } func (x *runSyscallAfterExecStop) afterLoad() {} -func (x *runSyscallAfterExecStop) load(m state.Map) { - m.Load("tc", &x.tc) + +func (x *runSyscallAfterExecStop) StateLoad(m state.Source) { + m.Load(0, &x.tc) +} + +func (x *ExitStatus) StateTypeName() string { + return "pkg/sentry/kernel.ExitStatus" +} + +func (x *ExitStatus) StateFields() []string { + return []string{ + "Code", + "Signo", + } } func (x *ExitStatus) beforeSave() {} -func (x *ExitStatus) save(m state.Map) { + +func (x *ExitStatus) StateSave(m state.Sink) { x.beforeSave() - m.Save("Code", &x.Code) - m.Save("Signo", &x.Signo) + m.Save(0, &x.Code) + m.Save(1, &x.Signo) } func (x *ExitStatus) afterLoad() {} -func (x *ExitStatus) load(m state.Map) { - m.Load("Code", &x.Code) - m.Load("Signo", &x.Signo) + +func (x *ExitStatus) StateLoad(m state.Source) { + m.Load(0, &x.Code) + m.Load(1, &x.Signo) +} + +func (x *runExit) StateTypeName() string { + return "pkg/sentry/kernel.runExit" +} + +func (x *runExit) StateFields() []string { + return []string{} } func (x *runExit) beforeSave() {} -func (x *runExit) save(m state.Map) { + +func (x *runExit) StateSave(m state.Sink) { x.beforeSave() } func (x *runExit) afterLoad() {} -func (x *runExit) load(m state.Map) { + +func (x *runExit) StateLoad(m state.Source) { +} + +func (x *runExitMain) StateTypeName() string { + return "pkg/sentry/kernel.runExitMain" +} + +func (x *runExitMain) StateFields() []string { + return []string{} } func (x *runExitMain) beforeSave() {} -func (x *runExitMain) save(m state.Map) { + +func (x *runExitMain) StateSave(m state.Sink) { x.beforeSave() } func (x *runExitMain) afterLoad() {} -func (x *runExitMain) load(m state.Map) { + +func (x *runExitMain) StateLoad(m state.Source) { +} + +func (x *runExitNotify) StateTypeName() string { + return "pkg/sentry/kernel.runExitNotify" +} + +func (x *runExitNotify) StateFields() []string { + return []string{} } func (x *runExitNotify) beforeSave() {} -func (x *runExitNotify) save(m state.Map) { + +func (x *runExitNotify) StateSave(m state.Sink) { x.beforeSave() } func (x *runExitNotify) afterLoad() {} -func (x *runExitNotify) load(m state.Map) { + +func (x *runExitNotify) StateLoad(m state.Source) { +} + +func (x *taskList) StateTypeName() string { + return "pkg/sentry/kernel.taskList" +} + +func (x *taskList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *taskList) beforeSave() {} -func (x *taskList) save(m state.Map) { + +func (x *taskList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *taskList) afterLoad() {} -func (x *taskList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *taskList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *taskEntry) StateTypeName() string { + return "pkg/sentry/kernel.taskEntry" +} + +func (x *taskEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *taskEntry) beforeSave() {} -func (x *taskEntry) save(m state.Map) { + +func (x *taskEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *taskEntry) afterLoad() {} -func (x *taskEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *taskEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) +} + +func (x *runApp) StateTypeName() string { + return "pkg/sentry/kernel.runApp" +} + +func (x *runApp) StateFields() []string { + return []string{} } func (x *runApp) beforeSave() {} -func (x *runApp) save(m state.Map) { + +func (x *runApp) StateSave(m state.Sink) { x.beforeSave() } func (x *runApp) afterLoad() {} -func (x *runApp) load(m state.Map) { + +func (x *runApp) StateLoad(m state.Source) { +} + +func (x *TaskGoroutineSchedInfo) StateTypeName() string { + return "pkg/sentry/kernel.TaskGoroutineSchedInfo" +} + +func (x *TaskGoroutineSchedInfo) StateFields() []string { + return []string{ + "Timestamp", + "State", + "UserTicks", + "SysTicks", + } } func (x *TaskGoroutineSchedInfo) beforeSave() {} -func (x *TaskGoroutineSchedInfo) save(m state.Map) { + +func (x *TaskGoroutineSchedInfo) StateSave(m state.Sink) { x.beforeSave() - m.Save("Timestamp", &x.Timestamp) - m.Save("State", &x.State) - m.Save("UserTicks", &x.UserTicks) - m.Save("SysTicks", &x.SysTicks) + m.Save(0, &x.Timestamp) + m.Save(1, &x.State) + m.Save(2, &x.UserTicks) + m.Save(3, &x.SysTicks) } func (x *TaskGoroutineSchedInfo) afterLoad() {} -func (x *TaskGoroutineSchedInfo) load(m state.Map) { - m.Load("Timestamp", &x.Timestamp) - m.Load("State", &x.State) - m.Load("UserTicks", &x.UserTicks) - m.Load("SysTicks", &x.SysTicks) + +func (x *TaskGoroutineSchedInfo) StateLoad(m state.Source) { + m.Load(0, &x.Timestamp) + m.Load(1, &x.State) + m.Load(2, &x.UserTicks) + m.Load(3, &x.SysTicks) +} + +func (x *taskClock) StateTypeName() string { + return "pkg/sentry/kernel.taskClock" +} + +func (x *taskClock) StateFields() []string { + return []string{ + "t", + "includeSys", + } } func (x *taskClock) beforeSave() {} -func (x *taskClock) save(m state.Map) { + +func (x *taskClock) StateSave(m state.Sink) { x.beforeSave() - m.Save("t", &x.t) - m.Save("includeSys", &x.includeSys) + m.Save(0, &x.t) + m.Save(1, &x.includeSys) } func (x *taskClock) afterLoad() {} -func (x *taskClock) load(m state.Map) { - m.Load("t", &x.t) - m.Load("includeSys", &x.includeSys) + +func (x *taskClock) StateLoad(m state.Source) { + m.Load(0, &x.t) + m.Load(1, &x.includeSys) +} + +func (x *tgClock) StateTypeName() string { + return "pkg/sentry/kernel.tgClock" +} + +func (x *tgClock) StateFields() []string { + return []string{ + "tg", + "includeSys", + } } func (x *tgClock) beforeSave() {} -func (x *tgClock) save(m state.Map) { + +func (x *tgClock) StateSave(m state.Sink) { x.beforeSave() - m.Save("tg", &x.tg) - m.Save("includeSys", &x.includeSys) + m.Save(0, &x.tg) + m.Save(1, &x.includeSys) } func (x *tgClock) afterLoad() {} -func (x *tgClock) load(m state.Map) { - m.Load("tg", &x.tg) - m.Load("includeSys", &x.includeSys) + +func (x *tgClock) StateLoad(m state.Source) { + m.Load(0, &x.tg) + m.Load(1, &x.includeSys) +} + +func (x *groupStop) StateTypeName() string { + return "pkg/sentry/kernel.groupStop" +} + +func (x *groupStop) StateFields() []string { + return []string{} } func (x *groupStop) beforeSave() {} -func (x *groupStop) save(m state.Map) { + +func (x *groupStop) StateSave(m state.Sink) { x.beforeSave() } func (x *groupStop) afterLoad() {} -func (x *groupStop) load(m state.Map) { + +func (x *groupStop) StateLoad(m state.Source) { +} + +func (x *runInterrupt) StateTypeName() string { + return "pkg/sentry/kernel.runInterrupt" +} + +func (x *runInterrupt) StateFields() []string { + return []string{} } func (x *runInterrupt) beforeSave() {} -func (x *runInterrupt) save(m state.Map) { + +func (x *runInterrupt) StateSave(m state.Sink) { x.beforeSave() } func (x *runInterrupt) afterLoad() {} -func (x *runInterrupt) load(m state.Map) { + +func (x *runInterrupt) StateLoad(m state.Source) { +} + +func (x *runInterruptAfterSignalDeliveryStop) StateTypeName() string { + return "pkg/sentry/kernel.runInterruptAfterSignalDeliveryStop" +} + +func (x *runInterruptAfterSignalDeliveryStop) StateFields() []string { + return []string{} } func (x *runInterruptAfterSignalDeliveryStop) beforeSave() {} -func (x *runInterruptAfterSignalDeliveryStop) save(m state.Map) { + +func (x *runInterruptAfterSignalDeliveryStop) StateSave(m state.Sink) { x.beforeSave() } func (x *runInterruptAfterSignalDeliveryStop) afterLoad() {} -func (x *runInterruptAfterSignalDeliveryStop) load(m state.Map) { + +func (x *runInterruptAfterSignalDeliveryStop) StateLoad(m state.Source) { +} + +func (x *runSyscallAfterSyscallEnterStop) StateTypeName() string { + return "pkg/sentry/kernel.runSyscallAfterSyscallEnterStop" +} + +func (x *runSyscallAfterSyscallEnterStop) StateFields() []string { + return []string{} } func (x *runSyscallAfterSyscallEnterStop) beforeSave() {} -func (x *runSyscallAfterSyscallEnterStop) save(m state.Map) { + +func (x *runSyscallAfterSyscallEnterStop) StateSave(m state.Sink) { x.beforeSave() } func (x *runSyscallAfterSyscallEnterStop) afterLoad() {} -func (x *runSyscallAfterSyscallEnterStop) load(m state.Map) { + +func (x *runSyscallAfterSyscallEnterStop) StateLoad(m state.Source) { +} + +func (x *runSyscallAfterSysemuStop) StateTypeName() string { + return "pkg/sentry/kernel.runSyscallAfterSysemuStop" +} + +func (x *runSyscallAfterSysemuStop) StateFields() []string { + return []string{} } func (x *runSyscallAfterSysemuStop) beforeSave() {} -func (x *runSyscallAfterSysemuStop) save(m state.Map) { + +func (x *runSyscallAfterSysemuStop) StateSave(m state.Sink) { x.beforeSave() } func (x *runSyscallAfterSysemuStop) afterLoad() {} -func (x *runSyscallAfterSysemuStop) load(m state.Map) { + +func (x *runSyscallAfterSysemuStop) StateLoad(m state.Source) { +} + +func (x *runSyscallReinvoke) StateTypeName() string { + return "pkg/sentry/kernel.runSyscallReinvoke" +} + +func (x *runSyscallReinvoke) StateFields() []string { + return []string{} } func (x *runSyscallReinvoke) beforeSave() {} -func (x *runSyscallReinvoke) save(m state.Map) { + +func (x *runSyscallReinvoke) StateSave(m state.Sink) { x.beforeSave() } func (x *runSyscallReinvoke) afterLoad() {} -func (x *runSyscallReinvoke) load(m state.Map) { + +func (x *runSyscallReinvoke) StateLoad(m state.Source) { +} + +func (x *runSyscallExit) StateTypeName() string { + return "pkg/sentry/kernel.runSyscallExit" +} + +func (x *runSyscallExit) StateFields() []string { + return []string{} } func (x *runSyscallExit) beforeSave() {} -func (x *runSyscallExit) save(m state.Map) { + +func (x *runSyscallExit) StateSave(m state.Sink) { x.beforeSave() } func (x *runSyscallExit) afterLoad() {} -func (x *runSyscallExit) load(m state.Map) { + +func (x *runSyscallExit) StateLoad(m state.Source) { +} + +func (x *ThreadGroup) StateTypeName() string { + return "pkg/sentry/kernel.ThreadGroup" +} + +func (x *ThreadGroup) StateFields() []string { + return []string{ + "threadGroupNode", + "signalHandlers", + "pendingSignals", + "groupStopDequeued", + "groupStopSignal", + "groupStopPendingCount", + "groupStopComplete", + "groupStopWaitable", + "groupContNotify", + "groupContInterrupted", + "groupContWaitable", + "exiting", + "exitStatus", + "terminationSignal", + "itimerRealTimer", + "itimerVirtSetting", + "itimerProfSetting", + "rlimitCPUSoftSetting", + "cpuTimersEnabled", + "timers", + "nextTimerID", + "exitedCPUStats", + "childCPUStats", + "ioUsage", + "maxRSS", + "childMaxRSS", + "limits", + "processGroup", + "execed", + "oldRSeqCritical", + "mounts", + "tty", + "oomScoreAdj", + } } func (x *ThreadGroup) beforeSave() {} -func (x *ThreadGroup) save(m state.Map) { + +func (x *ThreadGroup) StateSave(m state.Sink) { x.beforeSave() var oldRSeqCritical *OldRSeqCriticalRegion = x.saveOldRSeqCritical() - m.SaveValue("oldRSeqCritical", oldRSeqCritical) - m.Save("threadGroupNode", &x.threadGroupNode) - m.Save("signalHandlers", &x.signalHandlers) - m.Save("pendingSignals", &x.pendingSignals) - m.Save("groupStopDequeued", &x.groupStopDequeued) - m.Save("groupStopSignal", &x.groupStopSignal) - m.Save("groupStopPendingCount", &x.groupStopPendingCount) - m.Save("groupStopComplete", &x.groupStopComplete) - m.Save("groupStopWaitable", &x.groupStopWaitable) - m.Save("groupContNotify", &x.groupContNotify) - m.Save("groupContInterrupted", &x.groupContInterrupted) - m.Save("groupContWaitable", &x.groupContWaitable) - m.Save("exiting", &x.exiting) - m.Save("exitStatus", &x.exitStatus) - m.Save("terminationSignal", &x.terminationSignal) - m.Save("itimerRealTimer", &x.itimerRealTimer) - m.Save("itimerVirtSetting", &x.itimerVirtSetting) - m.Save("itimerProfSetting", &x.itimerProfSetting) - m.Save("rlimitCPUSoftSetting", &x.rlimitCPUSoftSetting) - m.Save("cpuTimersEnabled", &x.cpuTimersEnabled) - m.Save("timers", &x.timers) - m.Save("nextTimerID", &x.nextTimerID) - m.Save("exitedCPUStats", &x.exitedCPUStats) - m.Save("childCPUStats", &x.childCPUStats) - m.Save("ioUsage", &x.ioUsage) - m.Save("maxRSS", &x.maxRSS) - m.Save("childMaxRSS", &x.childMaxRSS) - m.Save("limits", &x.limits) - m.Save("processGroup", &x.processGroup) - m.Save("execed", &x.execed) - m.Save("mounts", &x.mounts) - m.Save("tty", &x.tty) - m.Save("oomScoreAdj", &x.oomScoreAdj) + m.SaveValue(29, oldRSeqCritical) + m.Save(0, &x.threadGroupNode) + m.Save(1, &x.signalHandlers) + m.Save(2, &x.pendingSignals) + m.Save(3, &x.groupStopDequeued) + m.Save(4, &x.groupStopSignal) + m.Save(5, &x.groupStopPendingCount) + m.Save(6, &x.groupStopComplete) + m.Save(7, &x.groupStopWaitable) + m.Save(8, &x.groupContNotify) + m.Save(9, &x.groupContInterrupted) + m.Save(10, &x.groupContWaitable) + m.Save(11, &x.exiting) + m.Save(12, &x.exitStatus) + m.Save(13, &x.terminationSignal) + m.Save(14, &x.itimerRealTimer) + m.Save(15, &x.itimerVirtSetting) + m.Save(16, &x.itimerProfSetting) + m.Save(17, &x.rlimitCPUSoftSetting) + m.Save(18, &x.cpuTimersEnabled) + m.Save(19, &x.timers) + m.Save(20, &x.nextTimerID) + m.Save(21, &x.exitedCPUStats) + m.Save(22, &x.childCPUStats) + m.Save(23, &x.ioUsage) + m.Save(24, &x.maxRSS) + m.Save(25, &x.childMaxRSS) + m.Save(26, &x.limits) + m.Save(27, &x.processGroup) + m.Save(28, &x.execed) + m.Save(30, &x.mounts) + m.Save(31, &x.tty) + m.Save(32, &x.oomScoreAdj) } func (x *ThreadGroup) afterLoad() {} -func (x *ThreadGroup) load(m state.Map) { - m.Load("threadGroupNode", &x.threadGroupNode) - m.Load("signalHandlers", &x.signalHandlers) - m.Load("pendingSignals", &x.pendingSignals) - m.Load("groupStopDequeued", &x.groupStopDequeued) - m.Load("groupStopSignal", &x.groupStopSignal) - m.Load("groupStopPendingCount", &x.groupStopPendingCount) - m.Load("groupStopComplete", &x.groupStopComplete) - m.Load("groupStopWaitable", &x.groupStopWaitable) - m.Load("groupContNotify", &x.groupContNotify) - m.Load("groupContInterrupted", &x.groupContInterrupted) - m.Load("groupContWaitable", &x.groupContWaitable) - m.Load("exiting", &x.exiting) - m.Load("exitStatus", &x.exitStatus) - m.Load("terminationSignal", &x.terminationSignal) - m.Load("itimerRealTimer", &x.itimerRealTimer) - m.Load("itimerVirtSetting", &x.itimerVirtSetting) - m.Load("itimerProfSetting", &x.itimerProfSetting) - m.Load("rlimitCPUSoftSetting", &x.rlimitCPUSoftSetting) - m.Load("cpuTimersEnabled", &x.cpuTimersEnabled) - m.Load("timers", &x.timers) - m.Load("nextTimerID", &x.nextTimerID) - m.Load("exitedCPUStats", &x.exitedCPUStats) - m.Load("childCPUStats", &x.childCPUStats) - m.Load("ioUsage", &x.ioUsage) - m.Load("maxRSS", &x.maxRSS) - m.Load("childMaxRSS", &x.childMaxRSS) - m.Load("limits", &x.limits) - m.Load("processGroup", &x.processGroup) - m.Load("execed", &x.execed) - m.Load("mounts", &x.mounts) - m.Load("tty", &x.tty) - m.Load("oomScoreAdj", &x.oomScoreAdj) - m.LoadValue("oldRSeqCritical", new(*OldRSeqCriticalRegion), func(y interface{}) { x.loadOldRSeqCritical(y.(*OldRSeqCriticalRegion)) }) + +func (x *ThreadGroup) StateLoad(m state.Source) { + m.Load(0, &x.threadGroupNode) + m.Load(1, &x.signalHandlers) + m.Load(2, &x.pendingSignals) + m.Load(3, &x.groupStopDequeued) + m.Load(4, &x.groupStopSignal) + m.Load(5, &x.groupStopPendingCount) + m.Load(6, &x.groupStopComplete) + m.Load(7, &x.groupStopWaitable) + m.Load(8, &x.groupContNotify) + m.Load(9, &x.groupContInterrupted) + m.Load(10, &x.groupContWaitable) + m.Load(11, &x.exiting) + m.Load(12, &x.exitStatus) + m.Load(13, &x.terminationSignal) + m.Load(14, &x.itimerRealTimer) + m.Load(15, &x.itimerVirtSetting) + m.Load(16, &x.itimerProfSetting) + m.Load(17, &x.rlimitCPUSoftSetting) + m.Load(18, &x.cpuTimersEnabled) + m.Load(19, &x.timers) + m.Load(20, &x.nextTimerID) + m.Load(21, &x.exitedCPUStats) + m.Load(22, &x.childCPUStats) + m.Load(23, &x.ioUsage) + m.Load(24, &x.maxRSS) + m.Load(25, &x.childMaxRSS) + m.Load(26, &x.limits) + m.Load(27, &x.processGroup) + m.Load(28, &x.execed) + m.Load(30, &x.mounts) + m.Load(31, &x.tty) + m.Load(32, &x.oomScoreAdj) + m.LoadValue(29, new(*OldRSeqCriticalRegion), func(y interface{}) { x.loadOldRSeqCritical(y.(*OldRSeqCriticalRegion)) }) +} + +func (x *itimerRealListener) StateTypeName() string { + return "pkg/sentry/kernel.itimerRealListener" +} + +func (x *itimerRealListener) StateFields() []string { + return []string{ + "tg", + } } func (x *itimerRealListener) beforeSave() {} -func (x *itimerRealListener) save(m state.Map) { + +func (x *itimerRealListener) StateSave(m state.Sink) { x.beforeSave() - m.Save("tg", &x.tg) + m.Save(0, &x.tg) } func (x *itimerRealListener) afterLoad() {} -func (x *itimerRealListener) load(m state.Map) { - m.Load("tg", &x.tg) + +func (x *itimerRealListener) StateLoad(m state.Source) { + m.Load(0, &x.tg) +} + +func (x *TaskSet) StateTypeName() string { + return "pkg/sentry/kernel.TaskSet" +} + +func (x *TaskSet) StateFields() []string { + return []string{ + "Root", + "sessions", + } } func (x *TaskSet) beforeSave() {} -func (x *TaskSet) save(m state.Map) { + +func (x *TaskSet) StateSave(m state.Sink) { x.beforeSave() - m.Save("Root", &x.Root) - m.Save("sessions", &x.sessions) + m.Save(0, &x.Root) + m.Save(1, &x.sessions) } func (x *TaskSet) afterLoad() {} -func (x *TaskSet) load(m state.Map) { - m.Load("Root", &x.Root) - m.Load("sessions", &x.sessions) + +func (x *TaskSet) StateLoad(m state.Source) { + m.Load(0, &x.Root) + m.Load(1, &x.sessions) +} + +func (x *PIDNamespace) StateTypeName() string { + return "pkg/sentry/kernel.PIDNamespace" +} + +func (x *PIDNamespace) StateFields() []string { + return []string{ + "owner", + "parent", + "userns", + "last", + "tasks", + "tids", + "tgids", + "sessions", + "sids", + "processGroups", + "pgids", + "exiting", + } } func (x *PIDNamespace) beforeSave() {} -func (x *PIDNamespace) save(m state.Map) { - x.beforeSave() - m.Save("owner", &x.owner) - m.Save("parent", &x.parent) - m.Save("userns", &x.userns) - m.Save("last", &x.last) - m.Save("tasks", &x.tasks) - m.Save("tids", &x.tids) - m.Save("tgids", &x.tgids) - m.Save("sessions", &x.sessions) - m.Save("sids", &x.sids) - m.Save("processGroups", &x.processGroups) - m.Save("pgids", &x.pgids) - m.Save("exiting", &x.exiting) + +func (x *PIDNamespace) StateSave(m state.Sink) { + x.beforeSave() + m.Save(0, &x.owner) + m.Save(1, &x.parent) + m.Save(2, &x.userns) + m.Save(3, &x.last) + m.Save(4, &x.tasks) + m.Save(5, &x.tids) + m.Save(6, &x.tgids) + m.Save(7, &x.sessions) + m.Save(8, &x.sids) + m.Save(9, &x.processGroups) + m.Save(10, &x.pgids) + m.Save(11, &x.exiting) } func (x *PIDNamespace) afterLoad() {} -func (x *PIDNamespace) load(m state.Map) { - m.Load("owner", &x.owner) - m.Load("parent", &x.parent) - m.Load("userns", &x.userns) - m.Load("last", &x.last) - m.Load("tasks", &x.tasks) - m.Load("tids", &x.tids) - m.Load("tgids", &x.tgids) - m.Load("sessions", &x.sessions) - m.Load("sids", &x.sids) - m.Load("processGroups", &x.processGroups) - m.Load("pgids", &x.pgids) - m.Load("exiting", &x.exiting) + +func (x *PIDNamespace) StateLoad(m state.Source) { + m.Load(0, &x.owner) + m.Load(1, &x.parent) + m.Load(2, &x.userns) + m.Load(3, &x.last) + m.Load(4, &x.tasks) + m.Load(5, &x.tids) + m.Load(6, &x.tgids) + m.Load(7, &x.sessions) + m.Load(8, &x.sids) + m.Load(9, &x.processGroups) + m.Load(10, &x.pgids) + m.Load(11, &x.exiting) +} + +func (x *threadGroupNode) StateTypeName() string { + return "pkg/sentry/kernel.threadGroupNode" +} + +func (x *threadGroupNode) StateFields() []string { + return []string{ + "pidns", + "leader", + "execing", + "tasks", + "tasksCount", + "liveTasks", + "activeTasks", + } } func (x *threadGroupNode) beforeSave() {} -func (x *threadGroupNode) save(m state.Map) { + +func (x *threadGroupNode) StateSave(m state.Sink) { x.beforeSave() - m.Save("pidns", &x.pidns) - m.Save("leader", &x.leader) - m.Save("execing", &x.execing) - m.Save("tasks", &x.tasks) - m.Save("tasksCount", &x.tasksCount) - m.Save("liveTasks", &x.liveTasks) - m.Save("activeTasks", &x.activeTasks) + m.Save(0, &x.pidns) + m.Save(1, &x.leader) + m.Save(2, &x.execing) + m.Save(3, &x.tasks) + m.Save(4, &x.tasksCount) + m.Save(5, &x.liveTasks) + m.Save(6, &x.activeTasks) } func (x *threadGroupNode) afterLoad() {} -func (x *threadGroupNode) load(m state.Map) { - m.Load("pidns", &x.pidns) - m.Load("leader", &x.leader) - m.Load("execing", &x.execing) - m.Load("tasks", &x.tasks) - m.Load("tasksCount", &x.tasksCount) - m.Load("liveTasks", &x.liveTasks) - m.Load("activeTasks", &x.activeTasks) + +func (x *threadGroupNode) StateLoad(m state.Source) { + m.Load(0, &x.pidns) + m.Load(1, &x.leader) + m.Load(2, &x.execing) + m.Load(3, &x.tasks) + m.Load(4, &x.tasksCount) + m.Load(5, &x.liveTasks) + m.Load(6, &x.activeTasks) +} + +func (x *taskNode) StateTypeName() string { + return "pkg/sentry/kernel.taskNode" +} + +func (x *taskNode) StateFields() []string { + return []string{ + "tg", + "taskEntry", + "parent", + "children", + "childPIDNamespace", + } } func (x *taskNode) beforeSave() {} -func (x *taskNode) save(m state.Map) { + +func (x *taskNode) StateSave(m state.Sink) { x.beforeSave() - m.Save("tg", &x.tg) - m.Save("taskEntry", &x.taskEntry) - m.Save("parent", &x.parent) - m.Save("children", &x.children) - m.Save("childPIDNamespace", &x.childPIDNamespace) + m.Save(0, &x.tg) + m.Save(1, &x.taskEntry) + m.Save(2, &x.parent) + m.Save(3, &x.children) + m.Save(4, &x.childPIDNamespace) } func (x *taskNode) afterLoad() {} -func (x *taskNode) load(m state.Map) { - m.LoadWait("tg", &x.tg) - m.Load("taskEntry", &x.taskEntry) - m.Load("parent", &x.parent) - m.Load("children", &x.children) - m.Load("childPIDNamespace", &x.childPIDNamespace) + +func (x *taskNode) StateLoad(m state.Source) { + m.LoadWait(0, &x.tg) + m.Load(1, &x.taskEntry) + m.Load(2, &x.parent) + m.Load(3, &x.children) + m.Load(4, &x.childPIDNamespace) +} + +func (x *Timekeeper) StateTypeName() string { + return "pkg/sentry/kernel.Timekeeper" } -func (x *Timekeeper) save(m state.Map) { +func (x *Timekeeper) StateFields() []string { + return []string{ + "bootTime", + "saveMonotonic", + "saveRealtime", + "params", + } +} + +func (x *Timekeeper) StateSave(m state.Sink) { x.beforeSave() - m.Save("bootTime", &x.bootTime) - m.Save("saveMonotonic", &x.saveMonotonic) - m.Save("saveRealtime", &x.saveRealtime) - m.Save("params", &x.params) + m.Save(0, &x.bootTime) + m.Save(1, &x.saveMonotonic) + m.Save(2, &x.saveRealtime) + m.Save(3, &x.params) } -func (x *Timekeeper) load(m state.Map) { - m.Load("bootTime", &x.bootTime) - m.Load("saveMonotonic", &x.saveMonotonic) - m.Load("saveRealtime", &x.saveRealtime) - m.Load("params", &x.params) +func (x *Timekeeper) StateLoad(m state.Source) { + m.Load(0, &x.bootTime) + m.Load(1, &x.saveMonotonic) + m.Load(2, &x.saveRealtime) + m.Load(3, &x.params) m.AfterLoad(x.afterLoad) } +func (x *timekeeperClock) StateTypeName() string { + return "pkg/sentry/kernel.timekeeperClock" +} + +func (x *timekeeperClock) StateFields() []string { + return []string{ + "tk", + "c", + } +} + func (x *timekeeperClock) beforeSave() {} -func (x *timekeeperClock) save(m state.Map) { + +func (x *timekeeperClock) StateSave(m state.Sink) { x.beforeSave() - m.Save("tk", &x.tk) - m.Save("c", &x.c) + m.Save(0, &x.tk) + m.Save(1, &x.c) } func (x *timekeeperClock) afterLoad() {} -func (x *timekeeperClock) load(m state.Map) { - m.Load("tk", &x.tk) - m.Load("c", &x.c) + +func (x *timekeeperClock) StateLoad(m state.Source) { + m.Load(0, &x.tk) + m.Load(1, &x.c) +} + +func (x *TTY) StateTypeName() string { + return "pkg/sentry/kernel.TTY" +} + +func (x *TTY) StateFields() []string { + return []string{ + "Index", + "tg", + } } func (x *TTY) beforeSave() {} -func (x *TTY) save(m state.Map) { + +func (x *TTY) StateSave(m state.Sink) { x.beforeSave() - m.Save("Index", &x.Index) - m.Save("tg", &x.tg) + m.Save(0, &x.Index) + m.Save(1, &x.tg) } func (x *TTY) afterLoad() {} -func (x *TTY) load(m state.Map) { - m.Load("Index", &x.Index) - m.Load("tg", &x.tg) + +func (x *TTY) StateLoad(m state.Source) { + m.Load(0, &x.Index) + m.Load(1, &x.tg) +} + +func (x *UTSNamespace) StateTypeName() string { + return "pkg/sentry/kernel.UTSNamespace" +} + +func (x *UTSNamespace) StateFields() []string { + return []string{ + "hostName", + "domainName", + "userns", + } } func (x *UTSNamespace) beforeSave() {} -func (x *UTSNamespace) save(m state.Map) { + +func (x *UTSNamespace) StateSave(m state.Sink) { x.beforeSave() - m.Save("hostName", &x.hostName) - m.Save("domainName", &x.domainName) - m.Save("userns", &x.userns) + m.Save(0, &x.hostName) + m.Save(1, &x.domainName) + m.Save(2, &x.userns) } func (x *UTSNamespace) afterLoad() {} -func (x *UTSNamespace) load(m state.Map) { - m.Load("hostName", &x.hostName) - m.Load("domainName", &x.domainName) - m.Load("userns", &x.userns) + +func (x *UTSNamespace) StateLoad(m state.Source) { + m.Load(0, &x.hostName) + m.Load(1, &x.domainName) + m.Load(2, &x.userns) +} + +func (x *VDSOParamPage) StateTypeName() string { + return "pkg/sentry/kernel.VDSOParamPage" +} + +func (x *VDSOParamPage) StateFields() []string { + return []string{ + "mfp", + "fr", + "seq", + } } func (x *VDSOParamPage) beforeSave() {} -func (x *VDSOParamPage) save(m state.Map) { + +func (x *VDSOParamPage) StateSave(m state.Sink) { x.beforeSave() - m.Save("mfp", &x.mfp) - m.Save("fr", &x.fr) - m.Save("seq", &x.seq) + m.Save(0, &x.mfp) + m.Save(1, &x.fr) + m.Save(2, &x.seq) } func (x *VDSOParamPage) afterLoad() {} -func (x *VDSOParamPage) load(m state.Map) { - m.Load("mfp", &x.mfp) - m.Load("fr", &x.fr) - m.Load("seq", &x.seq) + +func (x *VDSOParamPage) StateLoad(m state.Source) { + m.Load(0, &x.mfp) + m.Load(1, &x.fr) + m.Load(2, &x.seq) } func init() { - state.Register("pkg/sentry/kernel.abstractEndpoint", (*abstractEndpoint)(nil), state.Fns{Save: (*abstractEndpoint).save, Load: (*abstractEndpoint).load}) - state.Register("pkg/sentry/kernel.AbstractSocketNamespace", (*AbstractSocketNamespace)(nil), state.Fns{Save: (*AbstractSocketNamespace).save, Load: (*AbstractSocketNamespace).load}) - state.Register("pkg/sentry/kernel.FDFlags", (*FDFlags)(nil), state.Fns{Save: (*FDFlags).save, Load: (*FDFlags).load}) - state.Register("pkg/sentry/kernel.descriptor", (*descriptor)(nil), state.Fns{Save: (*descriptor).save, Load: (*descriptor).load}) - state.Register("pkg/sentry/kernel.FDTable", (*FDTable)(nil), state.Fns{Save: (*FDTable).save, Load: (*FDTable).load}) - state.Register("pkg/sentry/kernel.FSContext", (*FSContext)(nil), state.Fns{Save: (*FSContext).save, Load: (*FSContext).load}) - state.Register("pkg/sentry/kernel.IPCNamespace", (*IPCNamespace)(nil), state.Fns{Save: (*IPCNamespace).save, Load: (*IPCNamespace).load}) - state.Register("pkg/sentry/kernel.Kernel", (*Kernel)(nil), state.Fns{Save: (*Kernel).save, Load: (*Kernel).load}) - state.Register("pkg/sentry/kernel.SocketEntry", (*SocketEntry)(nil), state.Fns{Save: (*SocketEntry).save, Load: (*SocketEntry).load}) - state.Register("pkg/sentry/kernel.pendingSignals", (*pendingSignals)(nil), state.Fns{Save: (*pendingSignals).save, Load: (*pendingSignals).load}) - state.Register("pkg/sentry/kernel.pendingSignalQueue", (*pendingSignalQueue)(nil), state.Fns{Save: (*pendingSignalQueue).save, Load: (*pendingSignalQueue).load}) - state.Register("pkg/sentry/kernel.pendingSignal", (*pendingSignal)(nil), state.Fns{Save: (*pendingSignal).save, Load: (*pendingSignal).load}) - state.Register("pkg/sentry/kernel.pendingSignalList", (*pendingSignalList)(nil), state.Fns{Save: (*pendingSignalList).save, Load: (*pendingSignalList).load}) - state.Register("pkg/sentry/kernel.pendingSignalEntry", (*pendingSignalEntry)(nil), state.Fns{Save: (*pendingSignalEntry).save, Load: (*pendingSignalEntry).load}) - state.Register("pkg/sentry/kernel.savedPendingSignal", (*savedPendingSignal)(nil), state.Fns{Save: (*savedPendingSignal).save, Load: (*savedPendingSignal).load}) - state.Register("pkg/sentry/kernel.IntervalTimer", (*IntervalTimer)(nil), state.Fns{Save: (*IntervalTimer).save, Load: (*IntervalTimer).load}) - state.Register("pkg/sentry/kernel.processGroupList", (*processGroupList)(nil), state.Fns{Save: (*processGroupList).save, Load: (*processGroupList).load}) - state.Register("pkg/sentry/kernel.processGroupEntry", (*processGroupEntry)(nil), state.Fns{Save: (*processGroupEntry).save, Load: (*processGroupEntry).load}) - state.Register("pkg/sentry/kernel.ptraceOptions", (*ptraceOptions)(nil), state.Fns{Save: (*ptraceOptions).save, Load: (*ptraceOptions).load}) - state.Register("pkg/sentry/kernel.ptraceStop", (*ptraceStop)(nil), state.Fns{Save: (*ptraceStop).save, Load: (*ptraceStop).load}) - state.Register("pkg/sentry/kernel.OldRSeqCriticalRegion", (*OldRSeqCriticalRegion)(nil), state.Fns{Save: (*OldRSeqCriticalRegion).save, Load: (*OldRSeqCriticalRegion).load}) - state.Register("pkg/sentry/kernel.sessionList", (*sessionList)(nil), state.Fns{Save: (*sessionList).save, Load: (*sessionList).load}) - state.Register("pkg/sentry/kernel.sessionEntry", (*sessionEntry)(nil), state.Fns{Save: (*sessionEntry).save, Load: (*sessionEntry).load}) - state.Register("pkg/sentry/kernel.Session", (*Session)(nil), state.Fns{Save: (*Session).save, Load: (*Session).load}) - state.Register("pkg/sentry/kernel.ProcessGroup", (*ProcessGroup)(nil), state.Fns{Save: (*ProcessGroup).save, Load: (*ProcessGroup).load}) - state.Register("pkg/sentry/kernel.SignalHandlers", (*SignalHandlers)(nil), state.Fns{Save: (*SignalHandlers).save, Load: (*SignalHandlers).load}) - state.Register("pkg/sentry/kernel.socketList", (*socketList)(nil), state.Fns{Save: (*socketList).save, Load: (*socketList).load}) - state.Register("pkg/sentry/kernel.socketEntry", (*socketEntry)(nil), state.Fns{Save: (*socketEntry).save, Load: (*socketEntry).load}) - state.Register("pkg/sentry/kernel.syscallTableInfo", (*syscallTableInfo)(nil), state.Fns{Save: (*syscallTableInfo).save, Load: (*syscallTableInfo).load}) - state.Register("pkg/sentry/kernel.syslog", (*syslog)(nil), state.Fns{Save: (*syslog).save, Load: (*syslog).load}) - state.Register("pkg/sentry/kernel.Task", (*Task)(nil), state.Fns{Save: (*Task).save, Load: (*Task).load}) - state.Register("pkg/sentry/kernel.runSyscallAfterPtraceEventClone", (*runSyscallAfterPtraceEventClone)(nil), state.Fns{Save: (*runSyscallAfterPtraceEventClone).save, Load: (*runSyscallAfterPtraceEventClone).load}) - state.Register("pkg/sentry/kernel.runSyscallAfterVforkStop", (*runSyscallAfterVforkStop)(nil), state.Fns{Save: (*runSyscallAfterVforkStop).save, Load: (*runSyscallAfterVforkStop).load}) - state.Register("pkg/sentry/kernel.vforkStop", (*vforkStop)(nil), state.Fns{Save: (*vforkStop).save, Load: (*vforkStop).load}) - state.Register("pkg/sentry/kernel.TaskContext", (*TaskContext)(nil), state.Fns{Save: (*TaskContext).save, Load: (*TaskContext).load}) - state.Register("pkg/sentry/kernel.execStop", (*execStop)(nil), state.Fns{Save: (*execStop).save, Load: (*execStop).load}) - state.Register("pkg/sentry/kernel.runSyscallAfterExecStop", (*runSyscallAfterExecStop)(nil), state.Fns{Save: (*runSyscallAfterExecStop).save, Load: (*runSyscallAfterExecStop).load}) - state.Register("pkg/sentry/kernel.ExitStatus", (*ExitStatus)(nil), state.Fns{Save: (*ExitStatus).save, Load: (*ExitStatus).load}) - state.Register("pkg/sentry/kernel.runExit", (*runExit)(nil), state.Fns{Save: (*runExit).save, Load: (*runExit).load}) - state.Register("pkg/sentry/kernel.runExitMain", (*runExitMain)(nil), state.Fns{Save: (*runExitMain).save, Load: (*runExitMain).load}) - state.Register("pkg/sentry/kernel.runExitNotify", (*runExitNotify)(nil), state.Fns{Save: (*runExitNotify).save, Load: (*runExitNotify).load}) - state.Register("pkg/sentry/kernel.taskList", (*taskList)(nil), state.Fns{Save: (*taskList).save, Load: (*taskList).load}) - state.Register("pkg/sentry/kernel.taskEntry", (*taskEntry)(nil), state.Fns{Save: (*taskEntry).save, Load: (*taskEntry).load}) - state.Register("pkg/sentry/kernel.runApp", (*runApp)(nil), state.Fns{Save: (*runApp).save, Load: (*runApp).load}) - state.Register("pkg/sentry/kernel.TaskGoroutineSchedInfo", (*TaskGoroutineSchedInfo)(nil), state.Fns{Save: (*TaskGoroutineSchedInfo).save, Load: (*TaskGoroutineSchedInfo).load}) - state.Register("pkg/sentry/kernel.taskClock", (*taskClock)(nil), state.Fns{Save: (*taskClock).save, Load: (*taskClock).load}) - state.Register("pkg/sentry/kernel.tgClock", (*tgClock)(nil), state.Fns{Save: (*tgClock).save, Load: (*tgClock).load}) - state.Register("pkg/sentry/kernel.groupStop", (*groupStop)(nil), state.Fns{Save: (*groupStop).save, Load: (*groupStop).load}) - state.Register("pkg/sentry/kernel.runInterrupt", (*runInterrupt)(nil), state.Fns{Save: (*runInterrupt).save, Load: (*runInterrupt).load}) - state.Register("pkg/sentry/kernel.runInterruptAfterSignalDeliveryStop", (*runInterruptAfterSignalDeliveryStop)(nil), state.Fns{Save: (*runInterruptAfterSignalDeliveryStop).save, Load: (*runInterruptAfterSignalDeliveryStop).load}) - state.Register("pkg/sentry/kernel.runSyscallAfterSyscallEnterStop", (*runSyscallAfterSyscallEnterStop)(nil), state.Fns{Save: (*runSyscallAfterSyscallEnterStop).save, Load: (*runSyscallAfterSyscallEnterStop).load}) - state.Register("pkg/sentry/kernel.runSyscallAfterSysemuStop", (*runSyscallAfterSysemuStop)(nil), state.Fns{Save: (*runSyscallAfterSysemuStop).save, Load: (*runSyscallAfterSysemuStop).load}) - state.Register("pkg/sentry/kernel.runSyscallReinvoke", (*runSyscallReinvoke)(nil), state.Fns{Save: (*runSyscallReinvoke).save, Load: (*runSyscallReinvoke).load}) - state.Register("pkg/sentry/kernel.runSyscallExit", (*runSyscallExit)(nil), state.Fns{Save: (*runSyscallExit).save, Load: (*runSyscallExit).load}) - state.Register("pkg/sentry/kernel.ThreadGroup", (*ThreadGroup)(nil), state.Fns{Save: (*ThreadGroup).save, Load: (*ThreadGroup).load}) - state.Register("pkg/sentry/kernel.itimerRealListener", (*itimerRealListener)(nil), state.Fns{Save: (*itimerRealListener).save, Load: (*itimerRealListener).load}) - state.Register("pkg/sentry/kernel.TaskSet", (*TaskSet)(nil), state.Fns{Save: (*TaskSet).save, Load: (*TaskSet).load}) - state.Register("pkg/sentry/kernel.PIDNamespace", (*PIDNamespace)(nil), state.Fns{Save: (*PIDNamespace).save, Load: (*PIDNamespace).load}) - state.Register("pkg/sentry/kernel.threadGroupNode", (*threadGroupNode)(nil), state.Fns{Save: (*threadGroupNode).save, Load: (*threadGroupNode).load}) - state.Register("pkg/sentry/kernel.taskNode", (*taskNode)(nil), state.Fns{Save: (*taskNode).save, Load: (*taskNode).load}) - state.Register("pkg/sentry/kernel.Timekeeper", (*Timekeeper)(nil), state.Fns{Save: (*Timekeeper).save, Load: (*Timekeeper).load}) - state.Register("pkg/sentry/kernel.timekeeperClock", (*timekeeperClock)(nil), state.Fns{Save: (*timekeeperClock).save, Load: (*timekeeperClock).load}) - state.Register("pkg/sentry/kernel.TTY", (*TTY)(nil), state.Fns{Save: (*TTY).save, Load: (*TTY).load}) - state.Register("pkg/sentry/kernel.UTSNamespace", (*UTSNamespace)(nil), state.Fns{Save: (*UTSNamespace).save, Load: (*UTSNamespace).load}) - state.Register("pkg/sentry/kernel.VDSOParamPage", (*VDSOParamPage)(nil), state.Fns{Save: (*VDSOParamPage).save, Load: (*VDSOParamPage).load}) + state.Register((*abstractEndpoint)(nil)) + state.Register((*AbstractSocketNamespace)(nil)) + state.Register((*FDFlags)(nil)) + state.Register((*descriptor)(nil)) + state.Register((*FDTable)(nil)) + state.Register((*FSContext)(nil)) + state.Register((*IPCNamespace)(nil)) + state.Register((*Kernel)(nil)) + state.Register((*SocketEntry)(nil)) + state.Register((*pendingSignals)(nil)) + state.Register((*pendingSignalQueue)(nil)) + state.Register((*pendingSignal)(nil)) + state.Register((*pendingSignalList)(nil)) + state.Register((*pendingSignalEntry)(nil)) + state.Register((*savedPendingSignal)(nil)) + state.Register((*IntervalTimer)(nil)) + state.Register((*processGroupList)(nil)) + state.Register((*processGroupEntry)(nil)) + state.Register((*ptraceOptions)(nil)) + state.Register((*ptraceStop)(nil)) + state.Register((*OldRSeqCriticalRegion)(nil)) + state.Register((*sessionList)(nil)) + state.Register((*sessionEntry)(nil)) + state.Register((*Session)(nil)) + state.Register((*ProcessGroup)(nil)) + state.Register((*SignalHandlers)(nil)) + state.Register((*socketList)(nil)) + state.Register((*socketEntry)(nil)) + state.Register((*syscallTableInfo)(nil)) + state.Register((*syslog)(nil)) + state.Register((*Task)(nil)) + state.Register((*runSyscallAfterPtraceEventClone)(nil)) + state.Register((*runSyscallAfterVforkStop)(nil)) + state.Register((*vforkStop)(nil)) + state.Register((*TaskContext)(nil)) + state.Register((*execStop)(nil)) + state.Register((*runSyscallAfterExecStop)(nil)) + state.Register((*ExitStatus)(nil)) + state.Register((*runExit)(nil)) + state.Register((*runExitMain)(nil)) + state.Register((*runExitNotify)(nil)) + state.Register((*taskList)(nil)) + state.Register((*taskEntry)(nil)) + state.Register((*runApp)(nil)) + state.Register((*TaskGoroutineSchedInfo)(nil)) + state.Register((*taskClock)(nil)) + state.Register((*tgClock)(nil)) + state.Register((*groupStop)(nil)) + state.Register((*runInterrupt)(nil)) + state.Register((*runInterruptAfterSignalDeliveryStop)(nil)) + state.Register((*runSyscallAfterSyscallEnterStop)(nil)) + state.Register((*runSyscallAfterSysemuStop)(nil)) + state.Register((*runSyscallReinvoke)(nil)) + state.Register((*runSyscallExit)(nil)) + state.Register((*ThreadGroup)(nil)) + state.Register((*itimerRealListener)(nil)) + state.Register((*TaskSet)(nil)) + state.Register((*PIDNamespace)(nil)) + state.Register((*threadGroupNode)(nil)) + state.Register((*taskNode)(nil)) + state.Register((*Timekeeper)(nil)) + state.Register((*timekeeperClock)(nil)) + state.Register((*TTY)(nil)) + state.Register((*UTSNamespace)(nil)) + state.Register((*VDSOParamPage)(nil)) } diff --git a/pkg/sentry/kernel/pending_signals_list.go b/pkg/sentry/kernel/pending_signals_list.go index 2685c631a..d0062087a 100644 --- a/pkg/sentry/kernel/pending_signals_list.go +++ b/pkg/sentry/kernel/pending_signals_list.go @@ -56,7 +56,7 @@ func (l *pendingSignalList) Back() *pendingSignal { // // NOTE: This is an O(n) operation. func (l *pendingSignalList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (pendingSignalElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *pendingSignalList) Remove(e *pendingSignal) { if prev != nil { pendingSignalElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { pendingSignalElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/kernel/pipe/pipe_state_autogen.go b/pkg/sentry/kernel/pipe/pipe_state_autogen.go index b49ab46f9..df55abce6 100644 --- a/pkg/sentry/kernel/pipe/pipe_state_autogen.go +++ b/pkg/sentry/kernel/pipe/pipe_state_autogen.go @@ -6,79 +6,146 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *inodeOperations) StateTypeName() string { + return "pkg/sentry/kernel/pipe.inodeOperations" +} + +func (x *inodeOperations) StateFields() []string { + return []string{ + "InodeSimpleAttributes", + "p", + } +} + func (x *inodeOperations) beforeSave() {} -func (x *inodeOperations) save(m state.Map) { + +func (x *inodeOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Save("p", &x.p) + m.Save(0, &x.InodeSimpleAttributes) + m.Save(1, &x.p) } func (x *inodeOperations) afterLoad() {} -func (x *inodeOperations) load(m state.Map) { - m.Load("InodeSimpleAttributes", &x.InodeSimpleAttributes) - m.Load("p", &x.p) + +func (x *inodeOperations) StateLoad(m state.Source) { + m.Load(0, &x.InodeSimpleAttributes) + m.Load(1, &x.p) +} + +func (x *Pipe) StateTypeName() string { + return "pkg/sentry/kernel/pipe.Pipe" +} + +func (x *Pipe) StateFields() []string { + return []string{ + "isNamed", + "atomicIOBytes", + "readers", + "writers", + "view", + "max", + "hadWriter", + } } func (x *Pipe) beforeSave() {} -func (x *Pipe) save(m state.Map) { + +func (x *Pipe) StateSave(m state.Sink) { x.beforeSave() - m.Save("isNamed", &x.isNamed) - m.Save("atomicIOBytes", &x.atomicIOBytes) - m.Save("readers", &x.readers) - m.Save("writers", &x.writers) - m.Save("view", &x.view) - m.Save("max", &x.max) - m.Save("hadWriter", &x.hadWriter) + m.Save(0, &x.isNamed) + m.Save(1, &x.atomicIOBytes) + m.Save(2, &x.readers) + m.Save(3, &x.writers) + m.Save(4, &x.view) + m.Save(5, &x.max) + m.Save(6, &x.hadWriter) } func (x *Pipe) afterLoad() {} -func (x *Pipe) load(m state.Map) { - m.Load("isNamed", &x.isNamed) - m.Load("atomicIOBytes", &x.atomicIOBytes) - m.Load("readers", &x.readers) - m.Load("writers", &x.writers) - m.Load("view", &x.view) - m.Load("max", &x.max) - m.Load("hadWriter", &x.hadWriter) + +func (x *Pipe) StateLoad(m state.Source) { + m.Load(0, &x.isNamed) + m.Load(1, &x.atomicIOBytes) + m.Load(2, &x.readers) + m.Load(3, &x.writers) + m.Load(4, &x.view) + m.Load(5, &x.max) + m.Load(6, &x.hadWriter) +} + +func (x *Reader) StateTypeName() string { + return "pkg/sentry/kernel/pipe.Reader" +} + +func (x *Reader) StateFields() []string { + return []string{ + "ReaderWriter", + } } func (x *Reader) beforeSave() {} -func (x *Reader) save(m state.Map) { + +func (x *Reader) StateSave(m state.Sink) { x.beforeSave() - m.Save("ReaderWriter", &x.ReaderWriter) + m.Save(0, &x.ReaderWriter) } func (x *Reader) afterLoad() {} -func (x *Reader) load(m state.Map) { - m.Load("ReaderWriter", &x.ReaderWriter) + +func (x *Reader) StateLoad(m state.Source) { + m.Load(0, &x.ReaderWriter) +} + +func (x *ReaderWriter) StateTypeName() string { + return "pkg/sentry/kernel/pipe.ReaderWriter" +} + +func (x *ReaderWriter) StateFields() []string { + return []string{ + "Pipe", + } } func (x *ReaderWriter) beforeSave() {} -func (x *ReaderWriter) save(m state.Map) { + +func (x *ReaderWriter) StateSave(m state.Sink) { x.beforeSave() - m.Save("Pipe", &x.Pipe) + m.Save(0, &x.Pipe) } func (x *ReaderWriter) afterLoad() {} -func (x *ReaderWriter) load(m state.Map) { - m.Load("Pipe", &x.Pipe) + +func (x *ReaderWriter) StateLoad(m state.Source) { + m.Load(0, &x.Pipe) +} + +func (x *Writer) StateTypeName() string { + return "pkg/sentry/kernel/pipe.Writer" +} + +func (x *Writer) StateFields() []string { + return []string{ + "ReaderWriter", + } } func (x *Writer) beforeSave() {} -func (x *Writer) save(m state.Map) { + +func (x *Writer) StateSave(m state.Sink) { x.beforeSave() - m.Save("ReaderWriter", &x.ReaderWriter) + m.Save(0, &x.ReaderWriter) } func (x *Writer) afterLoad() {} -func (x *Writer) load(m state.Map) { - m.Load("ReaderWriter", &x.ReaderWriter) + +func (x *Writer) StateLoad(m state.Source) { + m.Load(0, &x.ReaderWriter) } func init() { - state.Register("pkg/sentry/kernel/pipe.inodeOperations", (*inodeOperations)(nil), state.Fns{Save: (*inodeOperations).save, Load: (*inodeOperations).load}) - state.Register("pkg/sentry/kernel/pipe.Pipe", (*Pipe)(nil), state.Fns{Save: (*Pipe).save, Load: (*Pipe).load}) - state.Register("pkg/sentry/kernel/pipe.Reader", (*Reader)(nil), state.Fns{Save: (*Reader).save, Load: (*Reader).load}) - state.Register("pkg/sentry/kernel/pipe.ReaderWriter", (*ReaderWriter)(nil), state.Fns{Save: (*ReaderWriter).save, Load: (*ReaderWriter).load}) - state.Register("pkg/sentry/kernel/pipe.Writer", (*Writer)(nil), state.Fns{Save: (*Writer).save, Load: (*Writer).load}) + state.Register((*inodeOperations)(nil)) + state.Register((*Pipe)(nil)) + state.Register((*Reader)(nil)) + state.Register((*ReaderWriter)(nil)) + state.Register((*Writer)(nil)) } diff --git a/pkg/sentry/kernel/process_group_list.go b/pkg/sentry/kernel/process_group_list.go index 3c5ea8aa7..bc2df5bce 100644 --- a/pkg/sentry/kernel/process_group_list.go +++ b/pkg/sentry/kernel/process_group_list.go @@ -56,7 +56,7 @@ func (l *processGroupList) Back() *ProcessGroup { // // NOTE: This is an O(n) operation. func (l *processGroupList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (processGroupElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *processGroupList) Remove(e *ProcessGroup) { if prev != nil { processGroupElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { processGroupElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/kernel/semaphore/semaphore_state_autogen.go b/pkg/sentry/kernel/semaphore/semaphore_state_autogen.go index ba1d073d9..fe5adfbee 100644 --- a/pkg/sentry/kernel/semaphore/semaphore_state_autogen.go +++ b/pkg/sentry/kernel/semaphore/semaphore_state_autogen.go @@ -6,112 +6,200 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *Registry) StateTypeName() string { + return "pkg/sentry/kernel/semaphore.Registry" +} + +func (x *Registry) StateFields() []string { + return []string{ + "userNS", + "semaphores", + "lastIDUsed", + } +} + func (x *Registry) beforeSave() {} -func (x *Registry) save(m state.Map) { + +func (x *Registry) StateSave(m state.Sink) { x.beforeSave() - m.Save("userNS", &x.userNS) - m.Save("semaphores", &x.semaphores) - m.Save("lastIDUsed", &x.lastIDUsed) + m.Save(0, &x.userNS) + m.Save(1, &x.semaphores) + m.Save(2, &x.lastIDUsed) } func (x *Registry) afterLoad() {} -func (x *Registry) load(m state.Map) { - m.Load("userNS", &x.userNS) - m.Load("semaphores", &x.semaphores) - m.Load("lastIDUsed", &x.lastIDUsed) + +func (x *Registry) StateLoad(m state.Source) { + m.Load(0, &x.userNS) + m.Load(1, &x.semaphores) + m.Load(2, &x.lastIDUsed) +} + +func (x *Set) StateTypeName() string { + return "pkg/sentry/kernel/semaphore.Set" +} + +func (x *Set) StateFields() []string { + return []string{ + "registry", + "ID", + "key", + "creator", + "owner", + "perms", + "opTime", + "changeTime", + "sems", + "dead", + } } func (x *Set) beforeSave() {} -func (x *Set) save(m state.Map) { + +func (x *Set) StateSave(m state.Sink) { x.beforeSave() - m.Save("registry", &x.registry) - m.Save("ID", &x.ID) - m.Save("key", &x.key) - m.Save("creator", &x.creator) - m.Save("owner", &x.owner) - m.Save("perms", &x.perms) - m.Save("opTime", &x.opTime) - m.Save("changeTime", &x.changeTime) - m.Save("sems", &x.sems) - m.Save("dead", &x.dead) + m.Save(0, &x.registry) + m.Save(1, &x.ID) + m.Save(2, &x.key) + m.Save(3, &x.creator) + m.Save(4, &x.owner) + m.Save(5, &x.perms) + m.Save(6, &x.opTime) + m.Save(7, &x.changeTime) + m.Save(8, &x.sems) + m.Save(9, &x.dead) } func (x *Set) afterLoad() {} -func (x *Set) load(m state.Map) { - m.Load("registry", &x.registry) - m.Load("ID", &x.ID) - m.Load("key", &x.key) - m.Load("creator", &x.creator) - m.Load("owner", &x.owner) - m.Load("perms", &x.perms) - m.Load("opTime", &x.opTime) - m.Load("changeTime", &x.changeTime) - m.Load("sems", &x.sems) - m.Load("dead", &x.dead) + +func (x *Set) StateLoad(m state.Source) { + m.Load(0, &x.registry) + m.Load(1, &x.ID) + m.Load(2, &x.key) + m.Load(3, &x.creator) + m.Load(4, &x.owner) + m.Load(5, &x.perms) + m.Load(6, &x.opTime) + m.Load(7, &x.changeTime) + m.Load(8, &x.sems) + m.Load(9, &x.dead) +} + +func (x *sem) StateTypeName() string { + return "pkg/sentry/kernel/semaphore.sem" +} + +func (x *sem) StateFields() []string { + return []string{ + "value", + "pid", + } } func (x *sem) beforeSave() {} -func (x *sem) save(m state.Map) { + +func (x *sem) StateSave(m state.Sink) { x.beforeSave() if !state.IsZeroValue(&x.waiters) { - m.Failf("waiters is %#v, expected zero", &x.waiters) + state.Failf("waiters is %#v, expected zero", &x.waiters) } - m.Save("value", &x.value) - m.Save("pid", &x.pid) + m.Save(0, &x.value) + m.Save(1, &x.pid) } func (x *sem) afterLoad() {} -func (x *sem) load(m state.Map) { - m.Load("value", &x.value) - m.Load("pid", &x.pid) + +func (x *sem) StateLoad(m state.Source) { + m.Load(0, &x.value) + m.Load(1, &x.pid) +} + +func (x *waiter) StateTypeName() string { + return "pkg/sentry/kernel/semaphore.waiter" +} + +func (x *waiter) StateFields() []string { + return []string{ + "waiterEntry", + "value", + "ch", + } } func (x *waiter) beforeSave() {} -func (x *waiter) save(m state.Map) { + +func (x *waiter) StateSave(m state.Sink) { x.beforeSave() - m.Save("waiterEntry", &x.waiterEntry) - m.Save("value", &x.value) - m.Save("ch", &x.ch) + m.Save(0, &x.waiterEntry) + m.Save(1, &x.value) + m.Save(2, &x.ch) } func (x *waiter) afterLoad() {} -func (x *waiter) load(m state.Map) { - m.Load("waiterEntry", &x.waiterEntry) - m.Load("value", &x.value) - m.Load("ch", &x.ch) + +func (x *waiter) StateLoad(m state.Source) { + m.Load(0, &x.waiterEntry) + m.Load(1, &x.value) + m.Load(2, &x.ch) +} + +func (x *waiterList) StateTypeName() string { + return "pkg/sentry/kernel/semaphore.waiterList" +} + +func (x *waiterList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *waiterList) beforeSave() {} -func (x *waiterList) save(m state.Map) { + +func (x *waiterList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *waiterList) afterLoad() {} -func (x *waiterList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *waiterList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *waiterEntry) StateTypeName() string { + return "pkg/sentry/kernel/semaphore.waiterEntry" +} + +func (x *waiterEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *waiterEntry) beforeSave() {} -func (x *waiterEntry) save(m state.Map) { + +func (x *waiterEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *waiterEntry) afterLoad() {} -func (x *waiterEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *waiterEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) } func init() { - state.Register("pkg/sentry/kernel/semaphore.Registry", (*Registry)(nil), state.Fns{Save: (*Registry).save, Load: (*Registry).load}) - state.Register("pkg/sentry/kernel/semaphore.Set", (*Set)(nil), state.Fns{Save: (*Set).save, Load: (*Set).load}) - state.Register("pkg/sentry/kernel/semaphore.sem", (*sem)(nil), state.Fns{Save: (*sem).save, Load: (*sem).load}) - state.Register("pkg/sentry/kernel/semaphore.waiter", (*waiter)(nil), state.Fns{Save: (*waiter).save, Load: (*waiter).load}) - state.Register("pkg/sentry/kernel/semaphore.waiterList", (*waiterList)(nil), state.Fns{Save: (*waiterList).save, Load: (*waiterList).load}) - state.Register("pkg/sentry/kernel/semaphore.waiterEntry", (*waiterEntry)(nil), state.Fns{Save: (*waiterEntry).save, Load: (*waiterEntry).load}) + state.Register((*Registry)(nil)) + state.Register((*Set)(nil)) + state.Register((*sem)(nil)) + state.Register((*waiter)(nil)) + state.Register((*waiterList)(nil)) + state.Register((*waiterEntry)(nil)) } diff --git a/pkg/sentry/kernel/semaphore/waiter_list.go b/pkg/sentry/kernel/semaphore/waiter_list.go index 4bfe5ff95..007bf67b0 100644 --- a/pkg/sentry/kernel/semaphore/waiter_list.go +++ b/pkg/sentry/kernel/semaphore/waiter_list.go @@ -56,7 +56,7 @@ func (l *waiterList) Back() *waiter { // // NOTE: This is an O(n) operation. func (l *waiterList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (waiterElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *waiterList) Remove(e *waiter) { if prev != nil { waiterElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { waiterElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/kernel/session_list.go b/pkg/sentry/kernel/session_list.go index 768482ab6..c328b2526 100644 --- a/pkg/sentry/kernel/session_list.go +++ b/pkg/sentry/kernel/session_list.go @@ -56,7 +56,7 @@ func (l *sessionList) Back() *Session { // // NOTE: This is an O(n) operation. func (l *sessionList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (sessionElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *sessionList) Remove(e *Session) { if prev != nil { sessionElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { sessionElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/kernel/shm/shm_state_autogen.go b/pkg/sentry/kernel/shm/shm_state_autogen.go index fa8f896f7..c98632087 100644 --- a/pkg/sentry/kernel/shm/shm_state_autogen.go +++ b/pkg/sentry/kernel/shm/shm_state_autogen.go @@ -6,69 +6,113 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *Registry) StateTypeName() string { + return "pkg/sentry/kernel/shm.Registry" +} + +func (x *Registry) StateFields() []string { + return []string{ + "userNS", + "shms", + "keysToShms", + "totalPages", + "lastIDUsed", + } +} + func (x *Registry) beforeSave() {} -func (x *Registry) save(m state.Map) { + +func (x *Registry) StateSave(m state.Sink) { x.beforeSave() - m.Save("userNS", &x.userNS) - m.Save("shms", &x.shms) - m.Save("keysToShms", &x.keysToShms) - m.Save("totalPages", &x.totalPages) - m.Save("lastIDUsed", &x.lastIDUsed) + m.Save(0, &x.userNS) + m.Save(1, &x.shms) + m.Save(2, &x.keysToShms) + m.Save(3, &x.totalPages) + m.Save(4, &x.lastIDUsed) } func (x *Registry) afterLoad() {} -func (x *Registry) load(m state.Map) { - m.Load("userNS", &x.userNS) - m.Load("shms", &x.shms) - m.Load("keysToShms", &x.keysToShms) - m.Load("totalPages", &x.totalPages) - m.Load("lastIDUsed", &x.lastIDUsed) + +func (x *Registry) StateLoad(m state.Source) { + m.Load(0, &x.userNS) + m.Load(1, &x.shms) + m.Load(2, &x.keysToShms) + m.Load(3, &x.totalPages) + m.Load(4, &x.lastIDUsed) +} + +func (x *Shm) StateTypeName() string { + return "pkg/sentry/kernel/shm.Shm" +} + +func (x *Shm) StateFields() []string { + return []string{ + "AtomicRefCount", + "mfp", + "registry", + "ID", + "creator", + "size", + "effectiveSize", + "fr", + "key", + "perms", + "owner", + "attachTime", + "detachTime", + "changeTime", + "creatorPID", + "lastAttachDetachPID", + "pendingDestruction", + } } func (x *Shm) beforeSave() {} -func (x *Shm) save(m state.Map) { + +func (x *Shm) StateSave(m state.Sink) { x.beforeSave() - m.Save("AtomicRefCount", &x.AtomicRefCount) - m.Save("mfp", &x.mfp) - m.Save("registry", &x.registry) - m.Save("ID", &x.ID) - m.Save("creator", &x.creator) - m.Save("size", &x.size) - m.Save("effectiveSize", &x.effectiveSize) - m.Save("fr", &x.fr) - m.Save("key", &x.key) - m.Save("perms", &x.perms) - m.Save("owner", &x.owner) - m.Save("attachTime", &x.attachTime) - m.Save("detachTime", &x.detachTime) - m.Save("changeTime", &x.changeTime) - m.Save("creatorPID", &x.creatorPID) - m.Save("lastAttachDetachPID", &x.lastAttachDetachPID) - m.Save("pendingDestruction", &x.pendingDestruction) + m.Save(0, &x.AtomicRefCount) + m.Save(1, &x.mfp) + m.Save(2, &x.registry) + m.Save(3, &x.ID) + m.Save(4, &x.creator) + m.Save(5, &x.size) + m.Save(6, &x.effectiveSize) + m.Save(7, &x.fr) + m.Save(8, &x.key) + m.Save(9, &x.perms) + m.Save(10, &x.owner) + m.Save(11, &x.attachTime) + m.Save(12, &x.detachTime) + m.Save(13, &x.changeTime) + m.Save(14, &x.creatorPID) + m.Save(15, &x.lastAttachDetachPID) + m.Save(16, &x.pendingDestruction) } func (x *Shm) afterLoad() {} -func (x *Shm) load(m state.Map) { - m.Load("AtomicRefCount", &x.AtomicRefCount) - m.Load("mfp", &x.mfp) - m.Load("registry", &x.registry) - m.Load("ID", &x.ID) - m.Load("creator", &x.creator) - m.Load("size", &x.size) - m.Load("effectiveSize", &x.effectiveSize) - m.Load("fr", &x.fr) - m.Load("key", &x.key) - m.Load("perms", &x.perms) - m.Load("owner", &x.owner) - m.Load("attachTime", &x.attachTime) - m.Load("detachTime", &x.detachTime) - m.Load("changeTime", &x.changeTime) - m.Load("creatorPID", &x.creatorPID) - m.Load("lastAttachDetachPID", &x.lastAttachDetachPID) - m.Load("pendingDestruction", &x.pendingDestruction) + +func (x *Shm) StateLoad(m state.Source) { + m.Load(0, &x.AtomicRefCount) + m.Load(1, &x.mfp) + m.Load(2, &x.registry) + m.Load(3, &x.ID) + m.Load(4, &x.creator) + m.Load(5, &x.size) + m.Load(6, &x.effectiveSize) + m.Load(7, &x.fr) + m.Load(8, &x.key) + m.Load(9, &x.perms) + m.Load(10, &x.owner) + m.Load(11, &x.attachTime) + m.Load(12, &x.detachTime) + m.Load(13, &x.changeTime) + m.Load(14, &x.creatorPID) + m.Load(15, &x.lastAttachDetachPID) + m.Load(16, &x.pendingDestruction) } func init() { - state.Register("pkg/sentry/kernel/shm.Registry", (*Registry)(nil), state.Fns{Save: (*Registry).save, Load: (*Registry).load}) - state.Register("pkg/sentry/kernel/shm.Shm", (*Shm)(nil), state.Fns{Save: (*Shm).save, Load: (*Shm).load}) + state.Register((*Registry)(nil)) + state.Register((*Shm)(nil)) } diff --git a/pkg/sentry/kernel/signalfd/signalfd_state_autogen.go b/pkg/sentry/kernel/signalfd/signalfd_state_autogen.go index 2ab5b4702..089a35b60 100644 --- a/pkg/sentry/kernel/signalfd/signalfd_state_autogen.go +++ b/pkg/sentry/kernel/signalfd/signalfd_state_autogen.go @@ -6,19 +6,32 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *SignalOperations) StateTypeName() string { + return "pkg/sentry/kernel/signalfd.SignalOperations" +} + +func (x *SignalOperations) StateFields() []string { + return []string{ + "target", + "mask", + } +} + func (x *SignalOperations) beforeSave() {} -func (x *SignalOperations) save(m state.Map) { + +func (x *SignalOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("target", &x.target) - m.Save("mask", &x.mask) + m.Save(0, &x.target) + m.Save(1, &x.mask) } func (x *SignalOperations) afterLoad() {} -func (x *SignalOperations) load(m state.Map) { - m.Load("target", &x.target) - m.Load("mask", &x.mask) + +func (x *SignalOperations) StateLoad(m state.Source) { + m.Load(0, &x.target) + m.Load(1, &x.mask) } func init() { - state.Register("pkg/sentry/kernel/signalfd.SignalOperations", (*SignalOperations)(nil), state.Fns{Save: (*SignalOperations).save, Load: (*SignalOperations).load}) + state.Register((*SignalOperations)(nil)) } diff --git a/pkg/sentry/kernel/socket_list.go b/pkg/sentry/kernel/socket_list.go index 294aa99fe..d2d4307a1 100644 --- a/pkg/sentry/kernel/socket_list.go +++ b/pkg/sentry/kernel/socket_list.go @@ -56,7 +56,7 @@ func (l *socketList) Back() *SocketEntry { // // NOTE: This is an O(n) operation. func (l *socketList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (socketElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *socketList) Remove(e *SocketEntry) { if prev != nil { socketElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { socketElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/kernel/task_list.go b/pkg/sentry/kernel/task_list.go index e7a3a3d20..f0c501845 100644 --- a/pkg/sentry/kernel/task_list.go +++ b/pkg/sentry/kernel/task_list.go @@ -56,7 +56,7 @@ func (l *taskList) Back() *Task { // // NOTE: This is an O(n) operation. func (l *taskList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (taskElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *taskList) Remove(e *Task) { if prev != nil { taskElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { taskElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/kernel/time/time_state_autogen.go b/pkg/sentry/kernel/time/time_state_autogen.go index ab6c6633d..4fb37df9a 100644 --- a/pkg/sentry/kernel/time/time_state_autogen.go +++ b/pkg/sentry/kernel/time/time_state_autogen.go @@ -6,51 +6,92 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *Time) StateTypeName() string { + return "pkg/sentry/kernel/time.Time" +} + +func (x *Time) StateFields() []string { + return []string{ + "ns", + } +} + func (x *Time) beforeSave() {} -func (x *Time) save(m state.Map) { + +func (x *Time) StateSave(m state.Sink) { x.beforeSave() - m.Save("ns", &x.ns) + m.Save(0, &x.ns) } func (x *Time) afterLoad() {} -func (x *Time) load(m state.Map) { - m.Load("ns", &x.ns) + +func (x *Time) StateLoad(m state.Source) { + m.Load(0, &x.ns) +} + +func (x *Setting) StateTypeName() string { + return "pkg/sentry/kernel/time.Setting" +} + +func (x *Setting) StateFields() []string { + return []string{ + "Enabled", + "Next", + "Period", + } } func (x *Setting) beforeSave() {} -func (x *Setting) save(m state.Map) { + +func (x *Setting) StateSave(m state.Sink) { x.beforeSave() - m.Save("Enabled", &x.Enabled) - m.Save("Next", &x.Next) - m.Save("Period", &x.Period) + m.Save(0, &x.Enabled) + m.Save(1, &x.Next) + m.Save(2, &x.Period) } func (x *Setting) afterLoad() {} -func (x *Setting) load(m state.Map) { - m.Load("Enabled", &x.Enabled) - m.Load("Next", &x.Next) - m.Load("Period", &x.Period) + +func (x *Setting) StateLoad(m state.Source) { + m.Load(0, &x.Enabled) + m.Load(1, &x.Next) + m.Load(2, &x.Period) +} + +func (x *Timer) StateTypeName() string { + return "pkg/sentry/kernel/time.Timer" +} + +func (x *Timer) StateFields() []string { + return []string{ + "clock", + "listener", + "setting", + "paused", + } } func (x *Timer) beforeSave() {} -func (x *Timer) save(m state.Map) { + +func (x *Timer) StateSave(m state.Sink) { x.beforeSave() - m.Save("clock", &x.clock) - m.Save("listener", &x.listener) - m.Save("setting", &x.setting) - m.Save("paused", &x.paused) + m.Save(0, &x.clock) + m.Save(1, &x.listener) + m.Save(2, &x.setting) + m.Save(3, &x.paused) } func (x *Timer) afterLoad() {} -func (x *Timer) load(m state.Map) { - m.Load("clock", &x.clock) - m.Load("listener", &x.listener) - m.Load("setting", &x.setting) - m.Load("paused", &x.paused) + +func (x *Timer) StateLoad(m state.Source) { + m.Load(0, &x.clock) + m.Load(1, &x.listener) + m.Load(2, &x.setting) + m.Load(3, &x.paused) } func init() { - state.Register("pkg/sentry/kernel/time.Time", (*Time)(nil), state.Fns{Save: (*Time).save, Load: (*Time).load}) - state.Register("pkg/sentry/kernel/time.Setting", (*Setting)(nil), state.Fns{Save: (*Setting).save, Load: (*Setting).load}) - state.Register("pkg/sentry/kernel/time.Timer", (*Timer)(nil), state.Fns{Save: (*Timer).save, Load: (*Timer).load}) + state.Register((*Time)(nil)) + state.Register((*Setting)(nil)) + state.Register((*Timer)(nil)) } diff --git a/pkg/sentry/limits/limits_state_autogen.go b/pkg/sentry/limits/limits_state_autogen.go index aa42533a9..72503d1d7 100644 --- a/pkg/sentry/limits/limits_state_autogen.go +++ b/pkg/sentry/limits/limits_state_autogen.go @@ -6,31 +6,56 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *Limit) StateTypeName() string { + return "pkg/sentry/limits.Limit" +} + +func (x *Limit) StateFields() []string { + return []string{ + "Cur", + "Max", + } +} + func (x *Limit) beforeSave() {} -func (x *Limit) save(m state.Map) { + +func (x *Limit) StateSave(m state.Sink) { x.beforeSave() - m.Save("Cur", &x.Cur) - m.Save("Max", &x.Max) + m.Save(0, &x.Cur) + m.Save(1, &x.Max) } func (x *Limit) afterLoad() {} -func (x *Limit) load(m state.Map) { - m.Load("Cur", &x.Cur) - m.Load("Max", &x.Max) + +func (x *Limit) StateLoad(m state.Source) { + m.Load(0, &x.Cur) + m.Load(1, &x.Max) +} + +func (x *LimitSet) StateTypeName() string { + return "pkg/sentry/limits.LimitSet" +} + +func (x *LimitSet) StateFields() []string { + return []string{ + "data", + } } func (x *LimitSet) beforeSave() {} -func (x *LimitSet) save(m state.Map) { + +func (x *LimitSet) StateSave(m state.Sink) { x.beforeSave() - m.Save("data", &x.data) + m.Save(0, &x.data) } func (x *LimitSet) afterLoad() {} -func (x *LimitSet) load(m state.Map) { - m.Load("data", &x.data) + +func (x *LimitSet) StateLoad(m state.Source) { + m.Load(0, &x.data) } func init() { - state.Register("pkg/sentry/limits.Limit", (*Limit)(nil), state.Fns{Save: (*Limit).save, Load: (*Limit).load}) - state.Register("pkg/sentry/limits.LimitSet", (*LimitSet)(nil), state.Fns{Save: (*LimitSet).save, Load: (*LimitSet).load}) + state.Register((*Limit)(nil)) + state.Register((*LimitSet)(nil)) } diff --git a/pkg/sentry/loader/loader_state_autogen.go b/pkg/sentry/loader/loader_state_autogen.go index e28667944..1b306bc6a 100644 --- a/pkg/sentry/loader/loader_state_autogen.go +++ b/pkg/sentry/loader/loader_state_autogen.go @@ -6,52 +6,87 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *VDSO) StateTypeName() string { + return "pkg/sentry/loader.VDSO" +} + +func (x *VDSO) StateFields() []string { + return []string{ + "ParamPage", + "vdso", + "os", + "arch", + "phdrs", + } +} + func (x *VDSO) beforeSave() {} -func (x *VDSO) save(m state.Map) { + +func (x *VDSO) StateSave(m state.Sink) { x.beforeSave() var phdrs []elfProgHeader = x.savePhdrs() - m.SaveValue("phdrs", phdrs) - m.Save("ParamPage", &x.ParamPage) - m.Save("vdso", &x.vdso) - m.Save("os", &x.os) - m.Save("arch", &x.arch) + m.SaveValue(4, phdrs) + m.Save(0, &x.ParamPage) + m.Save(1, &x.vdso) + m.Save(2, &x.os) + m.Save(3, &x.arch) } func (x *VDSO) afterLoad() {} -func (x *VDSO) load(m state.Map) { - m.Load("ParamPage", &x.ParamPage) - m.Load("vdso", &x.vdso) - m.Load("os", &x.os) - m.Load("arch", &x.arch) - m.LoadValue("phdrs", new([]elfProgHeader), func(y interface{}) { x.loadPhdrs(y.([]elfProgHeader)) }) + +func (x *VDSO) StateLoad(m state.Source) { + m.Load(0, &x.ParamPage) + m.Load(1, &x.vdso) + m.Load(2, &x.os) + m.Load(3, &x.arch) + m.LoadValue(4, new([]elfProgHeader), func(y interface{}) { x.loadPhdrs(y.([]elfProgHeader)) }) +} + +func (x *elfProgHeader) StateTypeName() string { + return "pkg/sentry/loader.elfProgHeader" +} + +func (x *elfProgHeader) StateFields() []string { + return []string{ + "Type", + "Flags", + "Off", + "Vaddr", + "Paddr", + "Filesz", + "Memsz", + "Align", + } } func (x *elfProgHeader) beforeSave() {} -func (x *elfProgHeader) save(m state.Map) { + +func (x *elfProgHeader) StateSave(m state.Sink) { x.beforeSave() - m.Save("Type", &x.Type) - m.Save("Flags", &x.Flags) - m.Save("Off", &x.Off) - m.Save("Vaddr", &x.Vaddr) - m.Save("Paddr", &x.Paddr) - m.Save("Filesz", &x.Filesz) - m.Save("Memsz", &x.Memsz) - m.Save("Align", &x.Align) + m.Save(0, &x.Type) + m.Save(1, &x.Flags) + m.Save(2, &x.Off) + m.Save(3, &x.Vaddr) + m.Save(4, &x.Paddr) + m.Save(5, &x.Filesz) + m.Save(6, &x.Memsz) + m.Save(7, &x.Align) } func (x *elfProgHeader) afterLoad() {} -func (x *elfProgHeader) load(m state.Map) { - m.Load("Type", &x.Type) - m.Load("Flags", &x.Flags) - m.Load("Off", &x.Off) - m.Load("Vaddr", &x.Vaddr) - m.Load("Paddr", &x.Paddr) - m.Load("Filesz", &x.Filesz) - m.Load("Memsz", &x.Memsz) - m.Load("Align", &x.Align) + +func (x *elfProgHeader) StateLoad(m state.Source) { + m.Load(0, &x.Type) + m.Load(1, &x.Flags) + m.Load(2, &x.Off) + m.Load(3, &x.Vaddr) + m.Load(4, &x.Paddr) + m.Load(5, &x.Filesz) + m.Load(6, &x.Memsz) + m.Load(7, &x.Align) } func init() { - state.Register("pkg/sentry/loader.VDSO", (*VDSO)(nil), state.Fns{Save: (*VDSO).save, Load: (*VDSO).load}) - state.Register("pkg/sentry/loader.elfProgHeader", (*elfProgHeader)(nil), state.Fns{Save: (*elfProgHeader).save, Load: (*elfProgHeader).load}) + state.Register((*VDSO)(nil)) + state.Register((*elfProgHeader)(nil)) } diff --git a/pkg/sentry/memmap/memmap_impl_state_autogen.go b/pkg/sentry/memmap/memmap_impl_state_autogen.go index b66b03884..ed4ab58cb 100644 --- a/pkg/sentry/memmap/memmap_impl_state_autogen.go +++ b/pkg/sentry/memmap/memmap_impl_state_autogen.go @@ -6,60 +6,105 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *MappingSet) StateTypeName() string { + return "pkg/sentry/memmap.MappingSet" +} + +func (x *MappingSet) StateFields() []string { + return []string{ + "root", + } +} + func (x *MappingSet) beforeSave() {} -func (x *MappingSet) save(m state.Map) { + +func (x *MappingSet) StateSave(m state.Sink) { x.beforeSave() var root *MappingSegmentDataSlices = x.saveRoot() - m.SaveValue("root", root) + m.SaveValue(0, root) } func (x *MappingSet) afterLoad() {} -func (x *MappingSet) load(m state.Map) { - m.LoadValue("root", new(*MappingSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*MappingSegmentDataSlices)) }) + +func (x *MappingSet) StateLoad(m state.Source) { + m.LoadValue(0, new(*MappingSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*MappingSegmentDataSlices)) }) +} + +func (x *Mappingnode) StateTypeName() string { + return "pkg/sentry/memmap.Mappingnode" +} + +func (x *Mappingnode) StateFields() []string { + return []string{ + "nrSegments", + "parent", + "parentIndex", + "hasChildren", + "maxGap", + "keys", + "values", + "children", + } } func (x *Mappingnode) beforeSave() {} -func (x *Mappingnode) save(m state.Map) { + +func (x *Mappingnode) StateSave(m state.Sink) { x.beforeSave() - m.Save("nrSegments", &x.nrSegments) - m.Save("parent", &x.parent) - m.Save("parentIndex", &x.parentIndex) - m.Save("hasChildren", &x.hasChildren) - m.Save("maxGap", &x.maxGap) - m.Save("keys", &x.keys) - m.Save("values", &x.values) - m.Save("children", &x.children) + m.Save(0, &x.nrSegments) + m.Save(1, &x.parent) + m.Save(2, &x.parentIndex) + m.Save(3, &x.hasChildren) + m.Save(4, &x.maxGap) + m.Save(5, &x.keys) + m.Save(6, &x.values) + m.Save(7, &x.children) } func (x *Mappingnode) afterLoad() {} -func (x *Mappingnode) load(m state.Map) { - m.Load("nrSegments", &x.nrSegments) - m.Load("parent", &x.parent) - m.Load("parentIndex", &x.parentIndex) - m.Load("hasChildren", &x.hasChildren) - m.Load("maxGap", &x.maxGap) - m.Load("keys", &x.keys) - m.Load("values", &x.values) - m.Load("children", &x.children) + +func (x *Mappingnode) StateLoad(m state.Source) { + m.Load(0, &x.nrSegments) + m.Load(1, &x.parent) + m.Load(2, &x.parentIndex) + m.Load(3, &x.hasChildren) + m.Load(4, &x.maxGap) + m.Load(5, &x.keys) + m.Load(6, &x.values) + m.Load(7, &x.children) +} + +func (x *MappingSegmentDataSlices) StateTypeName() string { + return "pkg/sentry/memmap.MappingSegmentDataSlices" +} + +func (x *MappingSegmentDataSlices) StateFields() []string { + return []string{ + "Start", + "End", + "Values", + } } func (x *MappingSegmentDataSlices) beforeSave() {} -func (x *MappingSegmentDataSlices) save(m state.Map) { + +func (x *MappingSegmentDataSlices) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) - m.Save("Values", &x.Values) + m.Save(0, &x.Start) + m.Save(1, &x.End) + m.Save(2, &x.Values) } func (x *MappingSegmentDataSlices) afterLoad() {} -func (x *MappingSegmentDataSlices) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) - m.Load("Values", &x.Values) + +func (x *MappingSegmentDataSlices) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) + m.Load(2, &x.Values) } func init() { - state.Register("pkg/sentry/memmap.MappingSet", (*MappingSet)(nil), state.Fns{Save: (*MappingSet).save, Load: (*MappingSet).load}) - state.Register("pkg/sentry/memmap.Mappingnode", (*Mappingnode)(nil), state.Fns{Save: (*Mappingnode).save, Load: (*Mappingnode).load}) - state.Register("pkg/sentry/memmap.MappingSegmentDataSlices", (*MappingSegmentDataSlices)(nil), state.Fns{Save: (*MappingSegmentDataSlices).save, Load: (*MappingSegmentDataSlices).load}) + state.Register((*MappingSet)(nil)) + state.Register((*Mappingnode)(nil)) + state.Register((*MappingSegmentDataSlices)(nil)) } diff --git a/pkg/sentry/memmap/memmap_state_autogen.go b/pkg/sentry/memmap/memmap_state_autogen.go index 2072dbad2..d7cd50786 100644 --- a/pkg/sentry/memmap/memmap_state_autogen.go +++ b/pkg/sentry/memmap/memmap_state_autogen.go @@ -6,35 +6,62 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *MappableRange) StateTypeName() string { + return "pkg/sentry/memmap.MappableRange" +} + +func (x *MappableRange) StateFields() []string { + return []string{ + "Start", + "End", + } +} + func (x *MappableRange) beforeSave() {} -func (x *MappableRange) save(m state.Map) { + +func (x *MappableRange) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) + m.Save(0, &x.Start) + m.Save(1, &x.End) } func (x *MappableRange) afterLoad() {} -func (x *MappableRange) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) + +func (x *MappableRange) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) +} + +func (x *MappingOfRange) StateTypeName() string { + return "pkg/sentry/memmap.MappingOfRange" +} + +func (x *MappingOfRange) StateFields() []string { + return []string{ + "MappingSpace", + "AddrRange", + "Writable", + } } func (x *MappingOfRange) beforeSave() {} -func (x *MappingOfRange) save(m state.Map) { + +func (x *MappingOfRange) StateSave(m state.Sink) { x.beforeSave() - m.Save("MappingSpace", &x.MappingSpace) - m.Save("AddrRange", &x.AddrRange) - m.Save("Writable", &x.Writable) + m.Save(0, &x.MappingSpace) + m.Save(1, &x.AddrRange) + m.Save(2, &x.Writable) } func (x *MappingOfRange) afterLoad() {} -func (x *MappingOfRange) load(m state.Map) { - m.Load("MappingSpace", &x.MappingSpace) - m.Load("AddrRange", &x.AddrRange) - m.Load("Writable", &x.Writable) + +func (x *MappingOfRange) StateLoad(m state.Source) { + m.Load(0, &x.MappingSpace) + m.Load(1, &x.AddrRange) + m.Load(2, &x.Writable) } func init() { - state.Register("pkg/sentry/memmap.MappableRange", (*MappableRange)(nil), state.Fns{Save: (*MappableRange).save, Load: (*MappableRange).load}) - state.Register("pkg/sentry/memmap.MappingOfRange", (*MappingOfRange)(nil), state.Fns{Save: (*MappingOfRange).save, Load: (*MappingOfRange).load}) + state.Register((*MappableRange)(nil)) + state.Register((*MappingOfRange)(nil)) } diff --git a/pkg/sentry/mm/io_list.go b/pkg/sentry/mm/io_list.go index ae0f19fc5..7cb6a98ad 100644 --- a/pkg/sentry/mm/io_list.go +++ b/pkg/sentry/mm/io_list.go @@ -56,7 +56,7 @@ func (l *ioList) Back() *ioResult { // // NOTE: This is an O(n) operation. func (l *ioList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (ioElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *ioList) Remove(e *ioResult) { if prev != nil { ioElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { ioElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/mm/mm_state_autogen.go b/pkg/sentry/mm/mm_state_autogen.go index fde35bcd8..2f81a8240 100644 --- a/pkg/sentry/mm/mm_state_autogen.go +++ b/pkg/sentry/mm/mm_state_autogen.go @@ -6,399 +6,707 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *aioManager) StateTypeName() string { + return "pkg/sentry/mm.aioManager" +} + +func (x *aioManager) StateFields() []string { + return []string{ + "contexts", + } +} + func (x *aioManager) beforeSave() {} -func (x *aioManager) save(m state.Map) { + +func (x *aioManager) StateSave(m state.Sink) { x.beforeSave() - m.Save("contexts", &x.contexts) + m.Save(0, &x.contexts) } func (x *aioManager) afterLoad() {} -func (x *aioManager) load(m state.Map) { - m.Load("contexts", &x.contexts) + +func (x *aioManager) StateLoad(m state.Source) { + m.Load(0, &x.contexts) +} + +func (x *ioResult) StateTypeName() string { + return "pkg/sentry/mm.ioResult" +} + +func (x *ioResult) StateFields() []string { + return []string{ + "data", + "ioEntry", + } } func (x *ioResult) beforeSave() {} -func (x *ioResult) save(m state.Map) { + +func (x *ioResult) StateSave(m state.Sink) { x.beforeSave() - m.Save("data", &x.data) - m.Save("ioEntry", &x.ioEntry) + m.Save(0, &x.data) + m.Save(1, &x.ioEntry) } func (x *ioResult) afterLoad() {} -func (x *ioResult) load(m state.Map) { - m.Load("data", &x.data) - m.Load("ioEntry", &x.ioEntry) + +func (x *ioResult) StateLoad(m state.Source) { + m.Load(0, &x.data) + m.Load(1, &x.ioEntry) +} + +func (x *AIOContext) StateTypeName() string { + return "pkg/sentry/mm.AIOContext" +} + +func (x *AIOContext) StateFields() []string { + return []string{ + "results", + "maxOutstanding", + "outstanding", + } } func (x *AIOContext) beforeSave() {} -func (x *AIOContext) save(m state.Map) { + +func (x *AIOContext) StateSave(m state.Sink) { x.beforeSave() if !state.IsZeroValue(&x.dead) { - m.Failf("dead is %#v, expected zero", &x.dead) + state.Failf("dead is %#v, expected zero", &x.dead) } - m.Save("results", &x.results) - m.Save("maxOutstanding", &x.maxOutstanding) - m.Save("outstanding", &x.outstanding) + m.Save(0, &x.results) + m.Save(1, &x.maxOutstanding) + m.Save(2, &x.outstanding) } -func (x *AIOContext) load(m state.Map) { - m.Load("results", &x.results) - m.Load("maxOutstanding", &x.maxOutstanding) - m.Load("outstanding", &x.outstanding) +func (x *AIOContext) StateLoad(m state.Source) { + m.Load(0, &x.results) + m.Load(1, &x.maxOutstanding) + m.Load(2, &x.outstanding) m.AfterLoad(x.afterLoad) } +func (x *aioMappable) StateTypeName() string { + return "pkg/sentry/mm.aioMappable" +} + +func (x *aioMappable) StateFields() []string { + return []string{ + "AtomicRefCount", + "mfp", + "fr", + } +} + func (x *aioMappable) beforeSave() {} -func (x *aioMappable) save(m state.Map) { + +func (x *aioMappable) StateSave(m state.Sink) { x.beforeSave() - m.Save("AtomicRefCount", &x.AtomicRefCount) - m.Save("mfp", &x.mfp) - m.Save("fr", &x.fr) + m.Save(0, &x.AtomicRefCount) + m.Save(1, &x.mfp) + m.Save(2, &x.fr) } func (x *aioMappable) afterLoad() {} -func (x *aioMappable) load(m state.Map) { - m.Load("AtomicRefCount", &x.AtomicRefCount) - m.Load("mfp", &x.mfp) - m.Load("fr", &x.fr) + +func (x *aioMappable) StateLoad(m state.Source) { + m.Load(0, &x.AtomicRefCount) + m.Load(1, &x.mfp) + m.Load(2, &x.fr) +} + +func (x *fileRefcountSet) StateTypeName() string { + return "pkg/sentry/mm.fileRefcountSet" +} + +func (x *fileRefcountSet) StateFields() []string { + return []string{ + "root", + } } func (x *fileRefcountSet) beforeSave() {} -func (x *fileRefcountSet) save(m state.Map) { + +func (x *fileRefcountSet) StateSave(m state.Sink) { x.beforeSave() var root *fileRefcountSegmentDataSlices = x.saveRoot() - m.SaveValue("root", root) + m.SaveValue(0, root) } func (x *fileRefcountSet) afterLoad() {} -func (x *fileRefcountSet) load(m state.Map) { - m.LoadValue("root", new(*fileRefcountSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*fileRefcountSegmentDataSlices)) }) + +func (x *fileRefcountSet) StateLoad(m state.Source) { + m.LoadValue(0, new(*fileRefcountSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*fileRefcountSegmentDataSlices)) }) +} + +func (x *fileRefcountnode) StateTypeName() string { + return "pkg/sentry/mm.fileRefcountnode" +} + +func (x *fileRefcountnode) StateFields() []string { + return []string{ + "nrSegments", + "parent", + "parentIndex", + "hasChildren", + "maxGap", + "keys", + "values", + "children", + } } func (x *fileRefcountnode) beforeSave() {} -func (x *fileRefcountnode) save(m state.Map) { + +func (x *fileRefcountnode) StateSave(m state.Sink) { x.beforeSave() - m.Save("nrSegments", &x.nrSegments) - m.Save("parent", &x.parent) - m.Save("parentIndex", &x.parentIndex) - m.Save("hasChildren", &x.hasChildren) - m.Save("maxGap", &x.maxGap) - m.Save("keys", &x.keys) - m.Save("values", &x.values) - m.Save("children", &x.children) + m.Save(0, &x.nrSegments) + m.Save(1, &x.parent) + m.Save(2, &x.parentIndex) + m.Save(3, &x.hasChildren) + m.Save(4, &x.maxGap) + m.Save(5, &x.keys) + m.Save(6, &x.values) + m.Save(7, &x.children) } func (x *fileRefcountnode) afterLoad() {} -func (x *fileRefcountnode) load(m state.Map) { - m.Load("nrSegments", &x.nrSegments) - m.Load("parent", &x.parent) - m.Load("parentIndex", &x.parentIndex) - m.Load("hasChildren", &x.hasChildren) - m.Load("maxGap", &x.maxGap) - m.Load("keys", &x.keys) - m.Load("values", &x.values) - m.Load("children", &x.children) + +func (x *fileRefcountnode) StateLoad(m state.Source) { + m.Load(0, &x.nrSegments) + m.Load(1, &x.parent) + m.Load(2, &x.parentIndex) + m.Load(3, &x.hasChildren) + m.Load(4, &x.maxGap) + m.Load(5, &x.keys) + m.Load(6, &x.values) + m.Load(7, &x.children) +} + +func (x *fileRefcountSegmentDataSlices) StateTypeName() string { + return "pkg/sentry/mm.fileRefcountSegmentDataSlices" +} + +func (x *fileRefcountSegmentDataSlices) StateFields() []string { + return []string{ + "Start", + "End", + "Values", + } } func (x *fileRefcountSegmentDataSlices) beforeSave() {} -func (x *fileRefcountSegmentDataSlices) save(m state.Map) { + +func (x *fileRefcountSegmentDataSlices) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) - m.Save("Values", &x.Values) + m.Save(0, &x.Start) + m.Save(1, &x.End) + m.Save(2, &x.Values) } func (x *fileRefcountSegmentDataSlices) afterLoad() {} -func (x *fileRefcountSegmentDataSlices) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) - m.Load("Values", &x.Values) + +func (x *fileRefcountSegmentDataSlices) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) + m.Load(2, &x.Values) +} + +func (x *ioList) StateTypeName() string { + return "pkg/sentry/mm.ioList" +} + +func (x *ioList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *ioList) beforeSave() {} -func (x *ioList) save(m state.Map) { + +func (x *ioList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *ioList) afterLoad() {} -func (x *ioList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *ioList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *ioEntry) StateTypeName() string { + return "pkg/sentry/mm.ioEntry" +} + +func (x *ioEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *ioEntry) beforeSave() {} -func (x *ioEntry) save(m state.Map) { + +func (x *ioEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *ioEntry) afterLoad() {} -func (x *ioEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *ioEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) +} + +func (x *MemoryManager) StateTypeName() string { + return "pkg/sentry/mm.MemoryManager" +} + +func (x *MemoryManager) StateFields() []string { + return []string{ + "p", + "mfp", + "layout", + "privateRefs", + "users", + "vmas", + "brk", + "usageAS", + "lockedAS", + "dataAS", + "defMLockMode", + "pmas", + "curRSS", + "maxRSS", + "argv", + "envv", + "auxv", + "executable", + "dumpability", + "aioManager", + "sleepForActivation", + "vdsoSigReturnAddr", + } } -func (x *MemoryManager) save(m state.Map) { +func (x *MemoryManager) StateSave(m state.Sink) { x.beforeSave() if !state.IsZeroValue(&x.active) { - m.Failf("active is %#v, expected zero", &x.active) + state.Failf("active is %#v, expected zero", &x.active) } if !state.IsZeroValue(&x.captureInvalidations) { - m.Failf("captureInvalidations is %#v, expected zero", &x.captureInvalidations) + state.Failf("captureInvalidations is %#v, expected zero", &x.captureInvalidations) } - m.Save("p", &x.p) - m.Save("mfp", &x.mfp) - m.Save("layout", &x.layout) - m.Save("privateRefs", &x.privateRefs) - m.Save("users", &x.users) - m.Save("vmas", &x.vmas) - m.Save("brk", &x.brk) - m.Save("usageAS", &x.usageAS) - m.Save("lockedAS", &x.lockedAS) - m.Save("dataAS", &x.dataAS) - m.Save("defMLockMode", &x.defMLockMode) - m.Save("pmas", &x.pmas) - m.Save("curRSS", &x.curRSS) - m.Save("maxRSS", &x.maxRSS) - m.Save("argv", &x.argv) - m.Save("envv", &x.envv) - m.Save("auxv", &x.auxv) - m.Save("executable", &x.executable) - m.Save("dumpability", &x.dumpability) - m.Save("aioManager", &x.aioManager) - m.Save("sleepForActivation", &x.sleepForActivation) - m.Save("vdsoSigReturnAddr", &x.vdsoSigReturnAddr) -} - -func (x *MemoryManager) load(m state.Map) { - m.Load("p", &x.p) - m.Load("mfp", &x.mfp) - m.Load("layout", &x.layout) - m.Load("privateRefs", &x.privateRefs) - m.Load("users", &x.users) - m.Load("vmas", &x.vmas) - m.Load("brk", &x.brk) - m.Load("usageAS", &x.usageAS) - m.Load("lockedAS", &x.lockedAS) - m.Load("dataAS", &x.dataAS) - m.Load("defMLockMode", &x.defMLockMode) - m.Load("pmas", &x.pmas) - m.Load("curRSS", &x.curRSS) - m.Load("maxRSS", &x.maxRSS) - m.Load("argv", &x.argv) - m.Load("envv", &x.envv) - m.Load("auxv", &x.auxv) - m.Load("executable", &x.executable) - m.Load("dumpability", &x.dumpability) - m.Load("aioManager", &x.aioManager) - m.Load("sleepForActivation", &x.sleepForActivation) - m.Load("vdsoSigReturnAddr", &x.vdsoSigReturnAddr) + m.Save(0, &x.p) + m.Save(1, &x.mfp) + m.Save(2, &x.layout) + m.Save(3, &x.privateRefs) + m.Save(4, &x.users) + m.Save(5, &x.vmas) + m.Save(6, &x.brk) + m.Save(7, &x.usageAS) + m.Save(8, &x.lockedAS) + m.Save(9, &x.dataAS) + m.Save(10, &x.defMLockMode) + m.Save(11, &x.pmas) + m.Save(12, &x.curRSS) + m.Save(13, &x.maxRSS) + m.Save(14, &x.argv) + m.Save(15, &x.envv) + m.Save(16, &x.auxv) + m.Save(17, &x.executable) + m.Save(18, &x.dumpability) + m.Save(19, &x.aioManager) + m.Save(20, &x.sleepForActivation) + m.Save(21, &x.vdsoSigReturnAddr) +} + +func (x *MemoryManager) StateLoad(m state.Source) { + m.Load(0, &x.p) + m.Load(1, &x.mfp) + m.Load(2, &x.layout) + m.Load(3, &x.privateRefs) + m.Load(4, &x.users) + m.Load(5, &x.vmas) + m.Load(6, &x.brk) + m.Load(7, &x.usageAS) + m.Load(8, &x.lockedAS) + m.Load(9, &x.dataAS) + m.Load(10, &x.defMLockMode) + m.Load(11, &x.pmas) + m.Load(12, &x.curRSS) + m.Load(13, &x.maxRSS) + m.Load(14, &x.argv) + m.Load(15, &x.envv) + m.Load(16, &x.auxv) + m.Load(17, &x.executable) + m.Load(18, &x.dumpability) + m.Load(19, &x.aioManager) + m.Load(20, &x.sleepForActivation) + m.Load(21, &x.vdsoSigReturnAddr) m.AfterLoad(x.afterLoad) } +func (x *vma) StateTypeName() string { + return "pkg/sentry/mm.vma" +} + +func (x *vma) StateFields() []string { + return []string{ + "mappable", + "off", + "realPerms", + "dontfork", + "mlockMode", + "numaPolicy", + "numaNodemask", + "id", + "hint", + } +} + func (x *vma) beforeSave() {} -func (x *vma) save(m state.Map) { + +func (x *vma) StateSave(m state.Sink) { x.beforeSave() var realPerms int = x.saveRealPerms() - m.SaveValue("realPerms", realPerms) - m.Save("mappable", &x.mappable) - m.Save("off", &x.off) - m.Save("dontfork", &x.dontfork) - m.Save("mlockMode", &x.mlockMode) - m.Save("numaPolicy", &x.numaPolicy) - m.Save("numaNodemask", &x.numaNodemask) - m.Save("id", &x.id) - m.Save("hint", &x.hint) + m.SaveValue(2, realPerms) + m.Save(0, &x.mappable) + m.Save(1, &x.off) + m.Save(3, &x.dontfork) + m.Save(4, &x.mlockMode) + m.Save(5, &x.numaPolicy) + m.Save(6, &x.numaNodemask) + m.Save(7, &x.id) + m.Save(8, &x.hint) } func (x *vma) afterLoad() {} -func (x *vma) load(m state.Map) { - m.Load("mappable", &x.mappable) - m.Load("off", &x.off) - m.Load("dontfork", &x.dontfork) - m.Load("mlockMode", &x.mlockMode) - m.Load("numaPolicy", &x.numaPolicy) - m.Load("numaNodemask", &x.numaNodemask) - m.Load("id", &x.id) - m.Load("hint", &x.hint) - m.LoadValue("realPerms", new(int), func(y interface{}) { x.loadRealPerms(y.(int)) }) + +func (x *vma) StateLoad(m state.Source) { + m.Load(0, &x.mappable) + m.Load(1, &x.off) + m.Load(3, &x.dontfork) + m.Load(4, &x.mlockMode) + m.Load(5, &x.numaPolicy) + m.Load(6, &x.numaNodemask) + m.Load(7, &x.id) + m.Load(8, &x.hint) + m.LoadValue(2, new(int), func(y interface{}) { x.loadRealPerms(y.(int)) }) +} + +func (x *pma) StateTypeName() string { + return "pkg/sentry/mm.pma" +} + +func (x *pma) StateFields() []string { + return []string{ + "off", + "translatePerms", + "effectivePerms", + "maxPerms", + "needCOW", + "private", + } } func (x *pma) beforeSave() {} -func (x *pma) save(m state.Map) { + +func (x *pma) StateSave(m state.Sink) { x.beforeSave() - m.Save("off", &x.off) - m.Save("translatePerms", &x.translatePerms) - m.Save("effectivePerms", &x.effectivePerms) - m.Save("maxPerms", &x.maxPerms) - m.Save("needCOW", &x.needCOW) - m.Save("private", &x.private) + m.Save(0, &x.off) + m.Save(1, &x.translatePerms) + m.Save(2, &x.effectivePerms) + m.Save(3, &x.maxPerms) + m.Save(4, &x.needCOW) + m.Save(5, &x.private) } func (x *pma) afterLoad() {} -func (x *pma) load(m state.Map) { - m.Load("off", &x.off) - m.Load("translatePerms", &x.translatePerms) - m.Load("effectivePerms", &x.effectivePerms) - m.Load("maxPerms", &x.maxPerms) - m.Load("needCOW", &x.needCOW) - m.Load("private", &x.private) + +func (x *pma) StateLoad(m state.Source) { + m.Load(0, &x.off) + m.Load(1, &x.translatePerms) + m.Load(2, &x.effectivePerms) + m.Load(3, &x.maxPerms) + m.Load(4, &x.needCOW) + m.Load(5, &x.private) +} + +func (x *privateRefs) StateTypeName() string { + return "pkg/sentry/mm.privateRefs" +} + +func (x *privateRefs) StateFields() []string { + return []string{ + "refs", + } } func (x *privateRefs) beforeSave() {} -func (x *privateRefs) save(m state.Map) { + +func (x *privateRefs) StateSave(m state.Sink) { x.beforeSave() - m.Save("refs", &x.refs) + m.Save(0, &x.refs) } func (x *privateRefs) afterLoad() {} -func (x *privateRefs) load(m state.Map) { - m.Load("refs", &x.refs) + +func (x *privateRefs) StateLoad(m state.Source) { + m.Load(0, &x.refs) +} + +func (x *pmaSet) StateTypeName() string { + return "pkg/sentry/mm.pmaSet" +} + +func (x *pmaSet) StateFields() []string { + return []string{ + "root", + } } func (x *pmaSet) beforeSave() {} -func (x *pmaSet) save(m state.Map) { + +func (x *pmaSet) StateSave(m state.Sink) { x.beforeSave() var root *pmaSegmentDataSlices = x.saveRoot() - m.SaveValue("root", root) + m.SaveValue(0, root) } func (x *pmaSet) afterLoad() {} -func (x *pmaSet) load(m state.Map) { - m.LoadValue("root", new(*pmaSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*pmaSegmentDataSlices)) }) + +func (x *pmaSet) StateLoad(m state.Source) { + m.LoadValue(0, new(*pmaSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*pmaSegmentDataSlices)) }) +} + +func (x *pmanode) StateTypeName() string { + return "pkg/sentry/mm.pmanode" +} + +func (x *pmanode) StateFields() []string { + return []string{ + "nrSegments", + "parent", + "parentIndex", + "hasChildren", + "maxGap", + "keys", + "values", + "children", + } } func (x *pmanode) beforeSave() {} -func (x *pmanode) save(m state.Map) { + +func (x *pmanode) StateSave(m state.Sink) { x.beforeSave() - m.Save("nrSegments", &x.nrSegments) - m.Save("parent", &x.parent) - m.Save("parentIndex", &x.parentIndex) - m.Save("hasChildren", &x.hasChildren) - m.Save("maxGap", &x.maxGap) - m.Save("keys", &x.keys) - m.Save("values", &x.values) - m.Save("children", &x.children) + m.Save(0, &x.nrSegments) + m.Save(1, &x.parent) + m.Save(2, &x.parentIndex) + m.Save(3, &x.hasChildren) + m.Save(4, &x.maxGap) + m.Save(5, &x.keys) + m.Save(6, &x.values) + m.Save(7, &x.children) } func (x *pmanode) afterLoad() {} -func (x *pmanode) load(m state.Map) { - m.Load("nrSegments", &x.nrSegments) - m.Load("parent", &x.parent) - m.Load("parentIndex", &x.parentIndex) - m.Load("hasChildren", &x.hasChildren) - m.Load("maxGap", &x.maxGap) - m.Load("keys", &x.keys) - m.Load("values", &x.values) - m.Load("children", &x.children) + +func (x *pmanode) StateLoad(m state.Source) { + m.Load(0, &x.nrSegments) + m.Load(1, &x.parent) + m.Load(2, &x.parentIndex) + m.Load(3, &x.hasChildren) + m.Load(4, &x.maxGap) + m.Load(5, &x.keys) + m.Load(6, &x.values) + m.Load(7, &x.children) +} + +func (x *pmaSegmentDataSlices) StateTypeName() string { + return "pkg/sentry/mm.pmaSegmentDataSlices" +} + +func (x *pmaSegmentDataSlices) StateFields() []string { + return []string{ + "Start", + "End", + "Values", + } } func (x *pmaSegmentDataSlices) beforeSave() {} -func (x *pmaSegmentDataSlices) save(m state.Map) { + +func (x *pmaSegmentDataSlices) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) - m.Save("Values", &x.Values) + m.Save(0, &x.Start) + m.Save(1, &x.End) + m.Save(2, &x.Values) } func (x *pmaSegmentDataSlices) afterLoad() {} -func (x *pmaSegmentDataSlices) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) - m.Load("Values", &x.Values) + +func (x *pmaSegmentDataSlices) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) + m.Load(2, &x.Values) +} + +func (x *SpecialMappable) StateTypeName() string { + return "pkg/sentry/mm.SpecialMappable" +} + +func (x *SpecialMappable) StateFields() []string { + return []string{ + "AtomicRefCount", + "mfp", + "fr", + "name", + } } func (x *SpecialMappable) beforeSave() {} -func (x *SpecialMappable) save(m state.Map) { + +func (x *SpecialMappable) StateSave(m state.Sink) { x.beforeSave() - m.Save("AtomicRefCount", &x.AtomicRefCount) - m.Save("mfp", &x.mfp) - m.Save("fr", &x.fr) - m.Save("name", &x.name) + m.Save(0, &x.AtomicRefCount) + m.Save(1, &x.mfp) + m.Save(2, &x.fr) + m.Save(3, &x.name) } func (x *SpecialMappable) afterLoad() {} -func (x *SpecialMappable) load(m state.Map) { - m.Load("AtomicRefCount", &x.AtomicRefCount) - m.Load("mfp", &x.mfp) - m.Load("fr", &x.fr) - m.Load("name", &x.name) + +func (x *SpecialMappable) StateLoad(m state.Source) { + m.Load(0, &x.AtomicRefCount) + m.Load(1, &x.mfp) + m.Load(2, &x.fr) + m.Load(3, &x.name) +} + +func (x *vmaSet) StateTypeName() string { + return "pkg/sentry/mm.vmaSet" +} + +func (x *vmaSet) StateFields() []string { + return []string{ + "root", + } } func (x *vmaSet) beforeSave() {} -func (x *vmaSet) save(m state.Map) { + +func (x *vmaSet) StateSave(m state.Sink) { x.beforeSave() var root *vmaSegmentDataSlices = x.saveRoot() - m.SaveValue("root", root) + m.SaveValue(0, root) } func (x *vmaSet) afterLoad() {} -func (x *vmaSet) load(m state.Map) { - m.LoadValue("root", new(*vmaSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*vmaSegmentDataSlices)) }) + +func (x *vmaSet) StateLoad(m state.Source) { + m.LoadValue(0, new(*vmaSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*vmaSegmentDataSlices)) }) +} + +func (x *vmanode) StateTypeName() string { + return "pkg/sentry/mm.vmanode" +} + +func (x *vmanode) StateFields() []string { + return []string{ + "nrSegments", + "parent", + "parentIndex", + "hasChildren", + "maxGap", + "keys", + "values", + "children", + } } func (x *vmanode) beforeSave() {} -func (x *vmanode) save(m state.Map) { + +func (x *vmanode) StateSave(m state.Sink) { x.beforeSave() - m.Save("nrSegments", &x.nrSegments) - m.Save("parent", &x.parent) - m.Save("parentIndex", &x.parentIndex) - m.Save("hasChildren", &x.hasChildren) - m.Save("maxGap", &x.maxGap) - m.Save("keys", &x.keys) - m.Save("values", &x.values) - m.Save("children", &x.children) + m.Save(0, &x.nrSegments) + m.Save(1, &x.parent) + m.Save(2, &x.parentIndex) + m.Save(3, &x.hasChildren) + m.Save(4, &x.maxGap) + m.Save(5, &x.keys) + m.Save(6, &x.values) + m.Save(7, &x.children) } func (x *vmanode) afterLoad() {} -func (x *vmanode) load(m state.Map) { - m.Load("nrSegments", &x.nrSegments) - m.Load("parent", &x.parent) - m.Load("parentIndex", &x.parentIndex) - m.Load("hasChildren", &x.hasChildren) - m.Load("maxGap", &x.maxGap) - m.Load("keys", &x.keys) - m.Load("values", &x.values) - m.Load("children", &x.children) + +func (x *vmanode) StateLoad(m state.Source) { + m.Load(0, &x.nrSegments) + m.Load(1, &x.parent) + m.Load(2, &x.parentIndex) + m.Load(3, &x.hasChildren) + m.Load(4, &x.maxGap) + m.Load(5, &x.keys) + m.Load(6, &x.values) + m.Load(7, &x.children) +} + +func (x *vmaSegmentDataSlices) StateTypeName() string { + return "pkg/sentry/mm.vmaSegmentDataSlices" +} + +func (x *vmaSegmentDataSlices) StateFields() []string { + return []string{ + "Start", + "End", + "Values", + } } func (x *vmaSegmentDataSlices) beforeSave() {} -func (x *vmaSegmentDataSlices) save(m state.Map) { + +func (x *vmaSegmentDataSlices) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) - m.Save("Values", &x.Values) + m.Save(0, &x.Start) + m.Save(1, &x.End) + m.Save(2, &x.Values) } func (x *vmaSegmentDataSlices) afterLoad() {} -func (x *vmaSegmentDataSlices) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) - m.Load("Values", &x.Values) + +func (x *vmaSegmentDataSlices) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) + m.Load(2, &x.Values) } func init() { - state.Register("pkg/sentry/mm.aioManager", (*aioManager)(nil), state.Fns{Save: (*aioManager).save, Load: (*aioManager).load}) - state.Register("pkg/sentry/mm.ioResult", (*ioResult)(nil), state.Fns{Save: (*ioResult).save, Load: (*ioResult).load}) - state.Register("pkg/sentry/mm.AIOContext", (*AIOContext)(nil), state.Fns{Save: (*AIOContext).save, Load: (*AIOContext).load}) - state.Register("pkg/sentry/mm.aioMappable", (*aioMappable)(nil), state.Fns{Save: (*aioMappable).save, Load: (*aioMappable).load}) - state.Register("pkg/sentry/mm.fileRefcountSet", (*fileRefcountSet)(nil), state.Fns{Save: (*fileRefcountSet).save, Load: (*fileRefcountSet).load}) - state.Register("pkg/sentry/mm.fileRefcountnode", (*fileRefcountnode)(nil), state.Fns{Save: (*fileRefcountnode).save, Load: (*fileRefcountnode).load}) - state.Register("pkg/sentry/mm.fileRefcountSegmentDataSlices", (*fileRefcountSegmentDataSlices)(nil), state.Fns{Save: (*fileRefcountSegmentDataSlices).save, Load: (*fileRefcountSegmentDataSlices).load}) - state.Register("pkg/sentry/mm.ioList", (*ioList)(nil), state.Fns{Save: (*ioList).save, Load: (*ioList).load}) - state.Register("pkg/sentry/mm.ioEntry", (*ioEntry)(nil), state.Fns{Save: (*ioEntry).save, Load: (*ioEntry).load}) - state.Register("pkg/sentry/mm.MemoryManager", (*MemoryManager)(nil), state.Fns{Save: (*MemoryManager).save, Load: (*MemoryManager).load}) - state.Register("pkg/sentry/mm.vma", (*vma)(nil), state.Fns{Save: (*vma).save, Load: (*vma).load}) - state.Register("pkg/sentry/mm.pma", (*pma)(nil), state.Fns{Save: (*pma).save, Load: (*pma).load}) - state.Register("pkg/sentry/mm.privateRefs", (*privateRefs)(nil), state.Fns{Save: (*privateRefs).save, Load: (*privateRefs).load}) - state.Register("pkg/sentry/mm.pmaSet", (*pmaSet)(nil), state.Fns{Save: (*pmaSet).save, Load: (*pmaSet).load}) - state.Register("pkg/sentry/mm.pmanode", (*pmanode)(nil), state.Fns{Save: (*pmanode).save, Load: (*pmanode).load}) - state.Register("pkg/sentry/mm.pmaSegmentDataSlices", (*pmaSegmentDataSlices)(nil), state.Fns{Save: (*pmaSegmentDataSlices).save, Load: (*pmaSegmentDataSlices).load}) - state.Register("pkg/sentry/mm.SpecialMappable", (*SpecialMappable)(nil), state.Fns{Save: (*SpecialMappable).save, Load: (*SpecialMappable).load}) - state.Register("pkg/sentry/mm.vmaSet", (*vmaSet)(nil), state.Fns{Save: (*vmaSet).save, Load: (*vmaSet).load}) - state.Register("pkg/sentry/mm.vmanode", (*vmanode)(nil), state.Fns{Save: (*vmanode).save, Load: (*vmanode).load}) - state.Register("pkg/sentry/mm.vmaSegmentDataSlices", (*vmaSegmentDataSlices)(nil), state.Fns{Save: (*vmaSegmentDataSlices).save, Load: (*vmaSegmentDataSlices).load}) + state.Register((*aioManager)(nil)) + state.Register((*ioResult)(nil)) + state.Register((*AIOContext)(nil)) + state.Register((*aioMappable)(nil)) + state.Register((*fileRefcountSet)(nil)) + state.Register((*fileRefcountnode)(nil)) + state.Register((*fileRefcountSegmentDataSlices)(nil)) + state.Register((*ioList)(nil)) + state.Register((*ioEntry)(nil)) + state.Register((*MemoryManager)(nil)) + state.Register((*vma)(nil)) + state.Register((*pma)(nil)) + state.Register((*privateRefs)(nil)) + state.Register((*pmaSet)(nil)) + state.Register((*pmanode)(nil)) + state.Register((*pmaSegmentDataSlices)(nil)) + state.Register((*SpecialMappable)(nil)) + state.Register((*vmaSet)(nil)) + state.Register((*vmanode)(nil)) + state.Register((*vmaSegmentDataSlices)(nil)) } diff --git a/pkg/sentry/pgalloc/pgalloc_state_autogen.go b/pkg/sentry/pgalloc/pgalloc_state_autogen.go index e9f37b729..5d2590b33 100644 --- a/pkg/sentry/pgalloc/pgalloc_state_autogen.go +++ b/pkg/sentry/pgalloc/pgalloc_state_autogen.go @@ -6,200 +6,362 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *EvictableRange) StateTypeName() string { + return "pkg/sentry/pgalloc.EvictableRange" +} + +func (x *EvictableRange) StateFields() []string { + return []string{ + "Start", + "End", + } +} + func (x *EvictableRange) beforeSave() {} -func (x *EvictableRange) save(m state.Map) { + +func (x *EvictableRange) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) + m.Save(0, &x.Start) + m.Save(1, &x.End) } func (x *EvictableRange) afterLoad() {} -func (x *EvictableRange) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) + +func (x *EvictableRange) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) +} + +func (x *evictableRangeSet) StateTypeName() string { + return "pkg/sentry/pgalloc.evictableRangeSet" +} + +func (x *evictableRangeSet) StateFields() []string { + return []string{ + "root", + } } func (x *evictableRangeSet) beforeSave() {} -func (x *evictableRangeSet) save(m state.Map) { + +func (x *evictableRangeSet) StateSave(m state.Sink) { x.beforeSave() var root *evictableRangeSegmentDataSlices = x.saveRoot() - m.SaveValue("root", root) + m.SaveValue(0, root) } func (x *evictableRangeSet) afterLoad() {} -func (x *evictableRangeSet) load(m state.Map) { - m.LoadValue("root", new(*evictableRangeSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*evictableRangeSegmentDataSlices)) }) + +func (x *evictableRangeSet) StateLoad(m state.Source) { + m.LoadValue(0, new(*evictableRangeSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*evictableRangeSegmentDataSlices)) }) +} + +func (x *evictableRangenode) StateTypeName() string { + return "pkg/sentry/pgalloc.evictableRangenode" +} + +func (x *evictableRangenode) StateFields() []string { + return []string{ + "nrSegments", + "parent", + "parentIndex", + "hasChildren", + "maxGap", + "keys", + "values", + "children", + } } func (x *evictableRangenode) beforeSave() {} -func (x *evictableRangenode) save(m state.Map) { + +func (x *evictableRangenode) StateSave(m state.Sink) { x.beforeSave() - m.Save("nrSegments", &x.nrSegments) - m.Save("parent", &x.parent) - m.Save("parentIndex", &x.parentIndex) - m.Save("hasChildren", &x.hasChildren) - m.Save("maxGap", &x.maxGap) - m.Save("keys", &x.keys) - m.Save("values", &x.values) - m.Save("children", &x.children) + m.Save(0, &x.nrSegments) + m.Save(1, &x.parent) + m.Save(2, &x.parentIndex) + m.Save(3, &x.hasChildren) + m.Save(4, &x.maxGap) + m.Save(5, &x.keys) + m.Save(6, &x.values) + m.Save(7, &x.children) } func (x *evictableRangenode) afterLoad() {} -func (x *evictableRangenode) load(m state.Map) { - m.Load("nrSegments", &x.nrSegments) - m.Load("parent", &x.parent) - m.Load("parentIndex", &x.parentIndex) - m.Load("hasChildren", &x.hasChildren) - m.Load("maxGap", &x.maxGap) - m.Load("keys", &x.keys) - m.Load("values", &x.values) - m.Load("children", &x.children) + +func (x *evictableRangenode) StateLoad(m state.Source) { + m.Load(0, &x.nrSegments) + m.Load(1, &x.parent) + m.Load(2, &x.parentIndex) + m.Load(3, &x.hasChildren) + m.Load(4, &x.maxGap) + m.Load(5, &x.keys) + m.Load(6, &x.values) + m.Load(7, &x.children) +} + +func (x *evictableRangeSegmentDataSlices) StateTypeName() string { + return "pkg/sentry/pgalloc.evictableRangeSegmentDataSlices" +} + +func (x *evictableRangeSegmentDataSlices) StateFields() []string { + return []string{ + "Start", + "End", + "Values", + } } func (x *evictableRangeSegmentDataSlices) beforeSave() {} -func (x *evictableRangeSegmentDataSlices) save(m state.Map) { + +func (x *evictableRangeSegmentDataSlices) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) - m.Save("Values", &x.Values) + m.Save(0, &x.Start) + m.Save(1, &x.End) + m.Save(2, &x.Values) } func (x *evictableRangeSegmentDataSlices) afterLoad() {} -func (x *evictableRangeSegmentDataSlices) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) - m.Load("Values", &x.Values) + +func (x *evictableRangeSegmentDataSlices) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) + m.Load(2, &x.Values) +} + +func (x *usageInfo) StateTypeName() string { + return "pkg/sentry/pgalloc.usageInfo" +} + +func (x *usageInfo) StateFields() []string { + return []string{ + "kind", + "knownCommitted", + "refs", + } } func (x *usageInfo) beforeSave() {} -func (x *usageInfo) save(m state.Map) { + +func (x *usageInfo) StateSave(m state.Sink) { x.beforeSave() - m.Save("kind", &x.kind) - m.Save("knownCommitted", &x.knownCommitted) - m.Save("refs", &x.refs) + m.Save(0, &x.kind) + m.Save(1, &x.knownCommitted) + m.Save(2, &x.refs) } func (x *usageInfo) afterLoad() {} -func (x *usageInfo) load(m state.Map) { - m.Load("kind", &x.kind) - m.Load("knownCommitted", &x.knownCommitted) - m.Load("refs", &x.refs) + +func (x *usageInfo) StateLoad(m state.Source) { + m.Load(0, &x.kind) + m.Load(1, &x.knownCommitted) + m.Load(2, &x.refs) +} + +func (x *reclaimSet) StateTypeName() string { + return "pkg/sentry/pgalloc.reclaimSet" +} + +func (x *reclaimSet) StateFields() []string { + return []string{ + "root", + } } func (x *reclaimSet) beforeSave() {} -func (x *reclaimSet) save(m state.Map) { + +func (x *reclaimSet) StateSave(m state.Sink) { x.beforeSave() var root *reclaimSegmentDataSlices = x.saveRoot() - m.SaveValue("root", root) + m.SaveValue(0, root) } func (x *reclaimSet) afterLoad() {} -func (x *reclaimSet) load(m state.Map) { - m.LoadValue("root", new(*reclaimSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*reclaimSegmentDataSlices)) }) + +func (x *reclaimSet) StateLoad(m state.Source) { + m.LoadValue(0, new(*reclaimSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*reclaimSegmentDataSlices)) }) +} + +func (x *reclaimnode) StateTypeName() string { + return "pkg/sentry/pgalloc.reclaimnode" +} + +func (x *reclaimnode) StateFields() []string { + return []string{ + "nrSegments", + "parent", + "parentIndex", + "hasChildren", + "maxGap", + "keys", + "values", + "children", + } } func (x *reclaimnode) beforeSave() {} -func (x *reclaimnode) save(m state.Map) { + +func (x *reclaimnode) StateSave(m state.Sink) { x.beforeSave() - m.Save("nrSegments", &x.nrSegments) - m.Save("parent", &x.parent) - m.Save("parentIndex", &x.parentIndex) - m.Save("hasChildren", &x.hasChildren) - m.Save("maxGap", &x.maxGap) - m.Save("keys", &x.keys) - m.Save("values", &x.values) - m.Save("children", &x.children) + m.Save(0, &x.nrSegments) + m.Save(1, &x.parent) + m.Save(2, &x.parentIndex) + m.Save(3, &x.hasChildren) + m.Save(4, &x.maxGap) + m.Save(5, &x.keys) + m.Save(6, &x.values) + m.Save(7, &x.children) } func (x *reclaimnode) afterLoad() {} -func (x *reclaimnode) load(m state.Map) { - m.Load("nrSegments", &x.nrSegments) - m.Load("parent", &x.parent) - m.Load("parentIndex", &x.parentIndex) - m.Load("hasChildren", &x.hasChildren) - m.Load("maxGap", &x.maxGap) - m.Load("keys", &x.keys) - m.Load("values", &x.values) - m.Load("children", &x.children) + +func (x *reclaimnode) StateLoad(m state.Source) { + m.Load(0, &x.nrSegments) + m.Load(1, &x.parent) + m.Load(2, &x.parentIndex) + m.Load(3, &x.hasChildren) + m.Load(4, &x.maxGap) + m.Load(5, &x.keys) + m.Load(6, &x.values) + m.Load(7, &x.children) +} + +func (x *reclaimSegmentDataSlices) StateTypeName() string { + return "pkg/sentry/pgalloc.reclaimSegmentDataSlices" +} + +func (x *reclaimSegmentDataSlices) StateFields() []string { + return []string{ + "Start", + "End", + "Values", + } } func (x *reclaimSegmentDataSlices) beforeSave() {} -func (x *reclaimSegmentDataSlices) save(m state.Map) { + +func (x *reclaimSegmentDataSlices) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) - m.Save("Values", &x.Values) + m.Save(0, &x.Start) + m.Save(1, &x.End) + m.Save(2, &x.Values) } func (x *reclaimSegmentDataSlices) afterLoad() {} -func (x *reclaimSegmentDataSlices) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) - m.Load("Values", &x.Values) + +func (x *reclaimSegmentDataSlices) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) + m.Load(2, &x.Values) +} + +func (x *usageSet) StateTypeName() string { + return "pkg/sentry/pgalloc.usageSet" +} + +func (x *usageSet) StateFields() []string { + return []string{ + "root", + } } func (x *usageSet) beforeSave() {} -func (x *usageSet) save(m state.Map) { + +func (x *usageSet) StateSave(m state.Sink) { x.beforeSave() var root *usageSegmentDataSlices = x.saveRoot() - m.SaveValue("root", root) + m.SaveValue(0, root) } func (x *usageSet) afterLoad() {} -func (x *usageSet) load(m state.Map) { - m.LoadValue("root", new(*usageSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*usageSegmentDataSlices)) }) + +func (x *usageSet) StateLoad(m state.Source) { + m.LoadValue(0, new(*usageSegmentDataSlices), func(y interface{}) { x.loadRoot(y.(*usageSegmentDataSlices)) }) +} + +func (x *usagenode) StateTypeName() string { + return "pkg/sentry/pgalloc.usagenode" +} + +func (x *usagenode) StateFields() []string { + return []string{ + "nrSegments", + "parent", + "parentIndex", + "hasChildren", + "maxGap", + "keys", + "values", + "children", + } } func (x *usagenode) beforeSave() {} -func (x *usagenode) save(m state.Map) { + +func (x *usagenode) StateSave(m state.Sink) { x.beforeSave() - m.Save("nrSegments", &x.nrSegments) - m.Save("parent", &x.parent) - m.Save("parentIndex", &x.parentIndex) - m.Save("hasChildren", &x.hasChildren) - m.Save("maxGap", &x.maxGap) - m.Save("keys", &x.keys) - m.Save("values", &x.values) - m.Save("children", &x.children) + m.Save(0, &x.nrSegments) + m.Save(1, &x.parent) + m.Save(2, &x.parentIndex) + m.Save(3, &x.hasChildren) + m.Save(4, &x.maxGap) + m.Save(5, &x.keys) + m.Save(6, &x.values) + m.Save(7, &x.children) } func (x *usagenode) afterLoad() {} -func (x *usagenode) load(m state.Map) { - m.Load("nrSegments", &x.nrSegments) - m.Load("parent", &x.parent) - m.Load("parentIndex", &x.parentIndex) - m.Load("hasChildren", &x.hasChildren) - m.Load("maxGap", &x.maxGap) - m.Load("keys", &x.keys) - m.Load("values", &x.values) - m.Load("children", &x.children) + +func (x *usagenode) StateLoad(m state.Source) { + m.Load(0, &x.nrSegments) + m.Load(1, &x.parent) + m.Load(2, &x.parentIndex) + m.Load(3, &x.hasChildren) + m.Load(4, &x.maxGap) + m.Load(5, &x.keys) + m.Load(6, &x.values) + m.Load(7, &x.children) +} + +func (x *usageSegmentDataSlices) StateTypeName() string { + return "pkg/sentry/pgalloc.usageSegmentDataSlices" +} + +func (x *usageSegmentDataSlices) StateFields() []string { + return []string{ + "Start", + "End", + "Values", + } } func (x *usageSegmentDataSlices) beforeSave() {} -func (x *usageSegmentDataSlices) save(m state.Map) { + +func (x *usageSegmentDataSlices) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) - m.Save("Values", &x.Values) + m.Save(0, &x.Start) + m.Save(1, &x.End) + m.Save(2, &x.Values) } func (x *usageSegmentDataSlices) afterLoad() {} -func (x *usageSegmentDataSlices) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) - m.Load("Values", &x.Values) + +func (x *usageSegmentDataSlices) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) + m.Load(2, &x.Values) } func init() { - state.Register("pkg/sentry/pgalloc.EvictableRange", (*EvictableRange)(nil), state.Fns{Save: (*EvictableRange).save, Load: (*EvictableRange).load}) - state.Register("pkg/sentry/pgalloc.evictableRangeSet", (*evictableRangeSet)(nil), state.Fns{Save: (*evictableRangeSet).save, Load: (*evictableRangeSet).load}) - state.Register("pkg/sentry/pgalloc.evictableRangenode", (*evictableRangenode)(nil), state.Fns{Save: (*evictableRangenode).save, Load: (*evictableRangenode).load}) - state.Register("pkg/sentry/pgalloc.evictableRangeSegmentDataSlices", (*evictableRangeSegmentDataSlices)(nil), state.Fns{Save: (*evictableRangeSegmentDataSlices).save, Load: (*evictableRangeSegmentDataSlices).load}) - state.Register("pkg/sentry/pgalloc.usageInfo", (*usageInfo)(nil), state.Fns{Save: (*usageInfo).save, Load: (*usageInfo).load}) - state.Register("pkg/sentry/pgalloc.reclaimSet", (*reclaimSet)(nil), state.Fns{Save: (*reclaimSet).save, Load: (*reclaimSet).load}) - state.Register("pkg/sentry/pgalloc.reclaimnode", (*reclaimnode)(nil), state.Fns{Save: (*reclaimnode).save, Load: (*reclaimnode).load}) - state.Register("pkg/sentry/pgalloc.reclaimSegmentDataSlices", (*reclaimSegmentDataSlices)(nil), state.Fns{Save: (*reclaimSegmentDataSlices).save, Load: (*reclaimSegmentDataSlices).load}) - state.Register("pkg/sentry/pgalloc.usageSet", (*usageSet)(nil), state.Fns{Save: (*usageSet).save, Load: (*usageSet).load}) - state.Register("pkg/sentry/pgalloc.usagenode", (*usagenode)(nil), state.Fns{Save: (*usagenode).save, Load: (*usagenode).load}) - state.Register("pkg/sentry/pgalloc.usageSegmentDataSlices", (*usageSegmentDataSlices)(nil), state.Fns{Save: (*usageSegmentDataSlices).save, Load: (*usageSegmentDataSlices).load}) + state.Register((*EvictableRange)(nil)) + state.Register((*evictableRangeSet)(nil)) + state.Register((*evictableRangenode)(nil)) + state.Register((*evictableRangeSegmentDataSlices)(nil)) + state.Register((*usageInfo)(nil)) + state.Register((*reclaimSet)(nil)) + state.Register((*reclaimnode)(nil)) + state.Register((*reclaimSegmentDataSlices)(nil)) + state.Register((*usageSet)(nil)) + state.Register((*usagenode)(nil)) + state.Register((*usageSegmentDataSlices)(nil)) } diff --git a/pkg/sentry/pgalloc/save_restore.go b/pkg/sentry/pgalloc/save_restore.go index f8385c146..78317fa35 100644 --- a/pkg/sentry/pgalloc/save_restore.go +++ b/pkg/sentry/pgalloc/save_restore.go @@ -26,11 +26,12 @@ import ( "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/pkg/sentry/usage" "gvisor.dev/gvisor/pkg/state" + "gvisor.dev/gvisor/pkg/state/wire" "gvisor.dev/gvisor/pkg/usermem" ) // SaveTo writes f's state to the given stream. -func (f *MemoryFile) SaveTo(ctx context.Context, w io.Writer) error { +func (f *MemoryFile) SaveTo(ctx context.Context, w wire.Writer) error { // Wait for reclaim. f.mu.Lock() defer f.mu.Unlock() @@ -79,10 +80,10 @@ func (f *MemoryFile) SaveTo(ctx context.Context, w io.Writer) error { } // Save metadata. - if err := state.Save(ctx, w, &f.fileSize, nil); err != nil { + if _, err := state.Save(ctx, w, &f.fileSize); err != nil { return err } - if err := state.Save(ctx, w, &f.usage, nil); err != nil { + if _, err := state.Save(ctx, w, &f.usage); err != nil { return err } @@ -115,9 +116,9 @@ func (f *MemoryFile) SaveTo(ctx context.Context, w io.Writer) error { } // LoadFrom loads MemoryFile state from the given stream. -func (f *MemoryFile) LoadFrom(ctx context.Context, r io.Reader) error { +func (f *MemoryFile) LoadFrom(ctx context.Context, r wire.Reader) error { // Load metadata. - if err := state.Load(ctx, r, &f.fileSize, nil); err != nil { + if _, err := state.Load(ctx, r, &f.fileSize); err != nil { return err } if err := f.file.Truncate(f.fileSize); err != nil { @@ -125,7 +126,7 @@ func (f *MemoryFile) LoadFrom(ctx context.Context, r io.Reader) error { } newMappings := make([]uintptr, f.fileSize>>chunkShift) f.mappings.Store(newMappings) - if err := state.Load(ctx, r, &f.usage, nil); err != nil { + if _, err := state.Load(ctx, r, &f.usage); err != nil { return err } diff --git a/pkg/sentry/platform/platform_state_autogen.go b/pkg/sentry/platform/platform_state_autogen.go index 7597195ef..696d2f9f1 100644 --- a/pkg/sentry/platform/platform_state_autogen.go +++ b/pkg/sentry/platform/platform_state_autogen.go @@ -6,19 +6,32 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *FileRange) StateTypeName() string { + return "pkg/sentry/platform.FileRange" +} + +func (x *FileRange) StateFields() []string { + return []string{ + "Start", + "End", + } +} + func (x *FileRange) beforeSave() {} -func (x *FileRange) save(m state.Map) { + +func (x *FileRange) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) + m.Save(0, &x.Start) + m.Save(1, &x.End) } func (x *FileRange) afterLoad() {} -func (x *FileRange) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) + +func (x *FileRange) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) } func init() { - state.Register("pkg/sentry/platform.FileRange", (*FileRange)(nil), state.Fns{Save: (*FileRange).save, Load: (*FileRange).load}) + state.Register((*FileRange)(nil)) } diff --git a/pkg/sentry/socket/control/control_state_autogen.go b/pkg/sentry/socket/control/control_state_autogen.go index 8a37b04c0..f3adf8927 100644 --- a/pkg/sentry/socket/control/control_state_autogen.go +++ b/pkg/sentry/socket/control/control_state_autogen.go @@ -3,34 +3,47 @@ package control import ( - "gvisor.dev/gvisor/pkg/sentry/fs" "gvisor.dev/gvisor/pkg/state" ) -func (x *RightsFiles) save(m state.Map) { - m.SaveValue("", ([]*fs.File)(*x)) +func (x *RightsFiles) StateTypeName() string { + return "pkg/sentry/socket/control.RightsFiles" } -func (x *RightsFiles) load(m state.Map) { - m.LoadValue("", new([]*fs.File), func(y interface{}) { *x = (RightsFiles)(y.([]*fs.File)) }) +func (x *RightsFiles) StateFields() []string { + return nil +} + +func (x *scmCredentials) StateTypeName() string { + return "pkg/sentry/socket/control.scmCredentials" +} + +func (x *scmCredentials) StateFields() []string { + return []string{ + "t", + "kuid", + "kgid", + } } func (x *scmCredentials) beforeSave() {} -func (x *scmCredentials) save(m state.Map) { + +func (x *scmCredentials) StateSave(m state.Sink) { x.beforeSave() - m.Save("t", &x.t) - m.Save("kuid", &x.kuid) - m.Save("kgid", &x.kgid) + m.Save(0, &x.t) + m.Save(1, &x.kuid) + m.Save(2, &x.kgid) } func (x *scmCredentials) afterLoad() {} -func (x *scmCredentials) load(m state.Map) { - m.Load("t", &x.t) - m.Load("kuid", &x.kuid) - m.Load("kgid", &x.kgid) + +func (x *scmCredentials) StateLoad(m state.Source) { + m.Load(0, &x.t) + m.Load(1, &x.kuid) + m.Load(2, &x.kgid) } func init() { - state.Register("pkg/sentry/socket/control.RightsFiles", (*RightsFiles)(nil), state.Fns{Save: (*RightsFiles).save, Load: (*RightsFiles).load}) - state.Register("pkg/sentry/socket/control.scmCredentials", (*scmCredentials)(nil), state.Fns{Save: (*scmCredentials).save, Load: (*scmCredentials).load}) + state.Register((*RightsFiles)(nil)) + state.Register((*scmCredentials)(nil)) } diff --git a/pkg/sentry/socket/hostinet/hostinet_state_autogen.go b/pkg/sentry/socket/hostinet/hostinet_state_autogen.go index 333811074..4ee4df33b 100644 --- a/pkg/sentry/socket/hostinet/hostinet_state_autogen.go +++ b/pkg/sentry/socket/hostinet/hostinet_state_autogen.go @@ -6,27 +6,44 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *socketOpsCommon) StateTypeName() string { + return "pkg/sentry/socket/hostinet.socketOpsCommon" +} + +func (x *socketOpsCommon) StateFields() []string { + return []string{ + "SendReceiveTimeout", + "family", + "stype", + "protocol", + "queue", + "fd", + } +} + func (x *socketOpsCommon) beforeSave() {} -func (x *socketOpsCommon) save(m state.Map) { + +func (x *socketOpsCommon) StateSave(m state.Sink) { x.beforeSave() - m.Save("SendReceiveTimeout", &x.SendReceiveTimeout) - m.Save("family", &x.family) - m.Save("stype", &x.stype) - m.Save("protocol", &x.protocol) - m.Save("queue", &x.queue) - m.Save("fd", &x.fd) + m.Save(0, &x.SendReceiveTimeout) + m.Save(1, &x.family) + m.Save(2, &x.stype) + m.Save(3, &x.protocol) + m.Save(4, &x.queue) + m.Save(5, &x.fd) } func (x *socketOpsCommon) afterLoad() {} -func (x *socketOpsCommon) load(m state.Map) { - m.Load("SendReceiveTimeout", &x.SendReceiveTimeout) - m.Load("family", &x.family) - m.Load("stype", &x.stype) - m.Load("protocol", &x.protocol) - m.Load("queue", &x.queue) - m.Load("fd", &x.fd) + +func (x *socketOpsCommon) StateLoad(m state.Source) { + m.Load(0, &x.SendReceiveTimeout) + m.Load(1, &x.family) + m.Load(2, &x.stype) + m.Load(3, &x.protocol) + m.Load(4, &x.queue) + m.Load(5, &x.fd) } func init() { - state.Register("pkg/sentry/socket/hostinet.socketOpsCommon", (*socketOpsCommon)(nil), state.Fns{Save: (*socketOpsCommon).save, Load: (*socketOpsCommon).load}) + state.Register((*socketOpsCommon)(nil)) } diff --git a/pkg/sentry/socket/netlink/netlink_state_autogen.go b/pkg/sentry/socket/netlink/netlink_state_autogen.go index fa6a7ce74..5a7a09b6d 100644 --- a/pkg/sentry/socket/netlink/netlink_state_autogen.go +++ b/pkg/sentry/socket/netlink/netlink_state_autogen.go @@ -6,59 +6,103 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *Socket) StateTypeName() string { + return "pkg/sentry/socket/netlink.Socket" +} + +func (x *Socket) StateFields() []string { + return []string{ + "socketOpsCommon", + } +} + func (x *Socket) beforeSave() {} -func (x *Socket) save(m state.Map) { + +func (x *Socket) StateSave(m state.Sink) { x.beforeSave() - m.Save("socketOpsCommon", &x.socketOpsCommon) + m.Save(0, &x.socketOpsCommon) } func (x *Socket) afterLoad() {} -func (x *Socket) load(m state.Map) { - m.Load("socketOpsCommon", &x.socketOpsCommon) + +func (x *Socket) StateLoad(m state.Source) { + m.Load(0, &x.socketOpsCommon) +} + +func (x *socketOpsCommon) StateTypeName() string { + return "pkg/sentry/socket/netlink.socketOpsCommon" +} + +func (x *socketOpsCommon) StateFields() []string { + return []string{ + "SendReceiveTimeout", + "ports", + "protocol", + "skType", + "ep", + "connection", + "bound", + "portID", + "sendBufferSize", + "passcred", + "filter", + } } func (x *socketOpsCommon) beforeSave() {} -func (x *socketOpsCommon) save(m state.Map) { + +func (x *socketOpsCommon) StateSave(m state.Sink) { x.beforeSave() - m.Save("SendReceiveTimeout", &x.SendReceiveTimeout) - m.Save("ports", &x.ports) - m.Save("protocol", &x.protocol) - m.Save("skType", &x.skType) - m.Save("ep", &x.ep) - m.Save("connection", &x.connection) - m.Save("bound", &x.bound) - m.Save("portID", &x.portID) - m.Save("sendBufferSize", &x.sendBufferSize) - m.Save("passcred", &x.passcred) - m.Save("filter", &x.filter) + m.Save(0, &x.SendReceiveTimeout) + m.Save(1, &x.ports) + m.Save(2, &x.protocol) + m.Save(3, &x.skType) + m.Save(4, &x.ep) + m.Save(5, &x.connection) + m.Save(6, &x.bound) + m.Save(7, &x.portID) + m.Save(8, &x.sendBufferSize) + m.Save(9, &x.passcred) + m.Save(10, &x.filter) } func (x *socketOpsCommon) afterLoad() {} -func (x *socketOpsCommon) load(m state.Map) { - m.Load("SendReceiveTimeout", &x.SendReceiveTimeout) - m.Load("ports", &x.ports) - m.Load("protocol", &x.protocol) - m.Load("skType", &x.skType) - m.Load("ep", &x.ep) - m.Load("connection", &x.connection) - m.Load("bound", &x.bound) - m.Load("portID", &x.portID) - m.Load("sendBufferSize", &x.sendBufferSize) - m.Load("passcred", &x.passcred) - m.Load("filter", &x.filter) + +func (x *socketOpsCommon) StateLoad(m state.Source) { + m.Load(0, &x.SendReceiveTimeout) + m.Load(1, &x.ports) + m.Load(2, &x.protocol) + m.Load(3, &x.skType) + m.Load(4, &x.ep) + m.Load(5, &x.connection) + m.Load(6, &x.bound) + m.Load(7, &x.portID) + m.Load(8, &x.sendBufferSize) + m.Load(9, &x.passcred) + m.Load(10, &x.filter) +} + +func (x *kernelSCM) StateTypeName() string { + return "pkg/sentry/socket/netlink.kernelSCM" +} + +func (x *kernelSCM) StateFields() []string { + return []string{} } func (x *kernelSCM) beforeSave() {} -func (x *kernelSCM) save(m state.Map) { + +func (x *kernelSCM) StateSave(m state.Sink) { x.beforeSave() } func (x *kernelSCM) afterLoad() {} -func (x *kernelSCM) load(m state.Map) { + +func (x *kernelSCM) StateLoad(m state.Source) { } func init() { - state.Register("pkg/sentry/socket/netlink.Socket", (*Socket)(nil), state.Fns{Save: (*Socket).save, Load: (*Socket).load}) - state.Register("pkg/sentry/socket/netlink.socketOpsCommon", (*socketOpsCommon)(nil), state.Fns{Save: (*socketOpsCommon).save, Load: (*socketOpsCommon).load}) - state.Register("pkg/sentry/socket/netlink.kernelSCM", (*kernelSCM)(nil), state.Fns{Save: (*kernelSCM).save, Load: (*kernelSCM).load}) + state.Register((*Socket)(nil)) + state.Register((*socketOpsCommon)(nil)) + state.Register((*kernelSCM)(nil)) } diff --git a/pkg/sentry/socket/netlink/port/port_state_autogen.go b/pkg/sentry/socket/netlink/port/port_state_autogen.go index c509cc7d5..16c59e616 100644 --- a/pkg/sentry/socket/netlink/port/port_state_autogen.go +++ b/pkg/sentry/socket/netlink/port/port_state_autogen.go @@ -6,17 +6,29 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *Manager) StateTypeName() string { + return "pkg/sentry/socket/netlink/port.Manager" +} + +func (x *Manager) StateFields() []string { + return []string{ + "ports", + } +} + func (x *Manager) beforeSave() {} -func (x *Manager) save(m state.Map) { + +func (x *Manager) StateSave(m state.Sink) { x.beforeSave() - m.Save("ports", &x.ports) + m.Save(0, &x.ports) } func (x *Manager) afterLoad() {} -func (x *Manager) load(m state.Map) { - m.Load("ports", &x.ports) + +func (x *Manager) StateLoad(m state.Source) { + m.Load(0, &x.ports) } func init() { - state.Register("pkg/sentry/socket/netlink/port.Manager", (*Manager)(nil), state.Fns{Save: (*Manager).save, Load: (*Manager).load}) + state.Register((*Manager)(nil)) } diff --git a/pkg/sentry/socket/netlink/route/route_state_autogen.go b/pkg/sentry/socket/netlink/route/route_state_autogen.go index bd10fe189..bc0111017 100644 --- a/pkg/sentry/socket/netlink/route/route_state_autogen.go +++ b/pkg/sentry/socket/netlink/route/route_state_autogen.go @@ -6,15 +6,25 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *Protocol) StateTypeName() string { + return "pkg/sentry/socket/netlink/route.Protocol" +} + +func (x *Protocol) StateFields() []string { + return []string{} +} + func (x *Protocol) beforeSave() {} -func (x *Protocol) save(m state.Map) { + +func (x *Protocol) StateSave(m state.Sink) { x.beforeSave() } func (x *Protocol) afterLoad() {} -func (x *Protocol) load(m state.Map) { + +func (x *Protocol) StateLoad(m state.Source) { } func init() { - state.Register("pkg/sentry/socket/netlink/route.Protocol", (*Protocol)(nil), state.Fns{Save: (*Protocol).save, Load: (*Protocol).load}) + state.Register((*Protocol)(nil)) } diff --git a/pkg/sentry/socket/netlink/uevent/uevent_state_autogen.go b/pkg/sentry/socket/netlink/uevent/uevent_state_autogen.go index b82dddf32..4f2211ec2 100644 --- a/pkg/sentry/socket/netlink/uevent/uevent_state_autogen.go +++ b/pkg/sentry/socket/netlink/uevent/uevent_state_autogen.go @@ -6,15 +6,25 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *Protocol) StateTypeName() string { + return "pkg/sentry/socket/netlink/uevent.Protocol" +} + +func (x *Protocol) StateFields() []string { + return []string{} +} + func (x *Protocol) beforeSave() {} -func (x *Protocol) save(m state.Map) { + +func (x *Protocol) StateSave(m state.Sink) { x.beforeSave() } func (x *Protocol) afterLoad() {} -func (x *Protocol) load(m state.Map) { + +func (x *Protocol) StateLoad(m state.Source) { } func init() { - state.Register("pkg/sentry/socket/netlink/uevent.Protocol", (*Protocol)(nil), state.Fns{Save: (*Protocol).save, Load: (*Protocol).load}) + state.Register((*Protocol)(nil)) } diff --git a/pkg/sentry/socket/netstack/netstack_state_autogen.go b/pkg/sentry/socket/netstack/netstack_state_autogen.go index a1f61607f..b7cf0b290 100644 --- a/pkg/sentry/socket/netstack/netstack_state_autogen.go +++ b/pkg/sentry/socket/netstack/netstack_state_autogen.go @@ -6,65 +6,111 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *SocketOperations) StateTypeName() string { + return "pkg/sentry/socket/netstack.SocketOperations" +} + +func (x *SocketOperations) StateFields() []string { + return []string{ + "socketOpsCommon", + } +} + func (x *SocketOperations) beforeSave() {} -func (x *SocketOperations) save(m state.Map) { + +func (x *SocketOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("socketOpsCommon", &x.socketOpsCommon) + m.Save(0, &x.socketOpsCommon) } func (x *SocketOperations) afterLoad() {} -func (x *SocketOperations) load(m state.Map) { - m.Load("socketOpsCommon", &x.socketOpsCommon) + +func (x *SocketOperations) StateLoad(m state.Source) { + m.Load(0, &x.socketOpsCommon) +} + +func (x *socketOpsCommon) StateTypeName() string { + return "pkg/sentry/socket/netstack.socketOpsCommon" +} + +func (x *socketOpsCommon) StateFields() []string { + return []string{ + "SendReceiveTimeout", + "Queue", + "family", + "Endpoint", + "skType", + "protocol", + "readViewHasData", + "readView", + "readCM", + "sender", + "sockOptTimestamp", + "timestampValid", + "timestampNS", + "sockOptInq", + } } func (x *socketOpsCommon) beforeSave() {} -func (x *socketOpsCommon) save(m state.Map) { + +func (x *socketOpsCommon) StateSave(m state.Sink) { x.beforeSave() - m.Save("SendReceiveTimeout", &x.SendReceiveTimeout) - m.Save("Queue", &x.Queue) - m.Save("family", &x.family) - m.Save("Endpoint", &x.Endpoint) - m.Save("skType", &x.skType) - m.Save("protocol", &x.protocol) - m.Save("readViewHasData", &x.readViewHasData) - m.Save("readView", &x.readView) - m.Save("readCM", &x.readCM) - m.Save("sender", &x.sender) - m.Save("sockOptTimestamp", &x.sockOptTimestamp) - m.Save("timestampValid", &x.timestampValid) - m.Save("timestampNS", &x.timestampNS) - m.Save("sockOptInq", &x.sockOptInq) + m.Save(0, &x.SendReceiveTimeout) + m.Save(1, &x.Queue) + m.Save(2, &x.family) + m.Save(3, &x.Endpoint) + m.Save(4, &x.skType) + m.Save(5, &x.protocol) + m.Save(6, &x.readViewHasData) + m.Save(7, &x.readView) + m.Save(8, &x.readCM) + m.Save(9, &x.sender) + m.Save(10, &x.sockOptTimestamp) + m.Save(11, &x.timestampValid) + m.Save(12, &x.timestampNS) + m.Save(13, &x.sockOptInq) } func (x *socketOpsCommon) afterLoad() {} -func (x *socketOpsCommon) load(m state.Map) { - m.Load("SendReceiveTimeout", &x.SendReceiveTimeout) - m.Load("Queue", &x.Queue) - m.Load("family", &x.family) - m.Load("Endpoint", &x.Endpoint) - m.Load("skType", &x.skType) - m.Load("protocol", &x.protocol) - m.Load("readViewHasData", &x.readViewHasData) - m.Load("readView", &x.readView) - m.Load("readCM", &x.readCM) - m.Load("sender", &x.sender) - m.Load("sockOptTimestamp", &x.sockOptTimestamp) - m.Load("timestampValid", &x.timestampValid) - m.Load("timestampNS", &x.timestampNS) - m.Load("sockOptInq", &x.sockOptInq) + +func (x *socketOpsCommon) StateLoad(m state.Source) { + m.Load(0, &x.SendReceiveTimeout) + m.Load(1, &x.Queue) + m.Load(2, &x.family) + m.Load(3, &x.Endpoint) + m.Load(4, &x.skType) + m.Load(5, &x.protocol) + m.Load(6, &x.readViewHasData) + m.Load(7, &x.readView) + m.Load(8, &x.readCM) + m.Load(9, &x.sender) + m.Load(10, &x.sockOptTimestamp) + m.Load(11, &x.timestampValid) + m.Load(12, &x.timestampNS) + m.Load(13, &x.sockOptInq) +} + +func (x *Stack) StateTypeName() string { + return "pkg/sentry/socket/netstack.Stack" +} + +func (x *Stack) StateFields() []string { + return []string{} } func (x *Stack) beforeSave() {} -func (x *Stack) save(m state.Map) { + +func (x *Stack) StateSave(m state.Sink) { x.beforeSave() } -func (x *Stack) load(m state.Map) { +func (x *Stack) StateLoad(m state.Source) { m.AfterLoad(x.afterLoad) } func init() { - state.Register("pkg/sentry/socket/netstack.SocketOperations", (*SocketOperations)(nil), state.Fns{Save: (*SocketOperations).save, Load: (*SocketOperations).load}) - state.Register("pkg/sentry/socket/netstack.socketOpsCommon", (*socketOpsCommon)(nil), state.Fns{Save: (*socketOpsCommon).save, Load: (*socketOpsCommon).load}) - state.Register("pkg/sentry/socket/netstack.Stack", (*Stack)(nil), state.Fns{Save: (*Stack).save, Load: (*Stack).load}) + state.Register((*SocketOperations)(nil)) + state.Register((*socketOpsCommon)(nil)) + state.Register((*Stack)(nil)) } diff --git a/pkg/sentry/socket/socket_state_autogen.go b/pkg/sentry/socket/socket_state_autogen.go index 900c217c7..2865933e9 100644 --- a/pkg/sentry/socket/socket_state_autogen.go +++ b/pkg/sentry/socket/socket_state_autogen.go @@ -6,19 +6,32 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *SendReceiveTimeout) StateTypeName() string { + return "pkg/sentry/socket.SendReceiveTimeout" +} + +func (x *SendReceiveTimeout) StateFields() []string { + return []string{ + "send", + "recv", + } +} + func (x *SendReceiveTimeout) beforeSave() {} -func (x *SendReceiveTimeout) save(m state.Map) { + +func (x *SendReceiveTimeout) StateSave(m state.Sink) { x.beforeSave() - m.Save("send", &x.send) - m.Save("recv", &x.recv) + m.Save(0, &x.send) + m.Save(1, &x.recv) } func (x *SendReceiveTimeout) afterLoad() {} -func (x *SendReceiveTimeout) load(m state.Map) { - m.Load("send", &x.send) - m.Load("recv", &x.recv) + +func (x *SendReceiveTimeout) StateLoad(m state.Source) { + m.Load(0, &x.send) + m.Load(1, &x.recv) } func init() { - state.Register("pkg/sentry/socket.SendReceiveTimeout", (*SendReceiveTimeout)(nil), state.Fns{Save: (*SendReceiveTimeout).save, Load: (*SendReceiveTimeout).load}) + state.Register((*SendReceiveTimeout)(nil)) } diff --git a/pkg/sentry/socket/unix/transport/transport_message_list.go b/pkg/sentry/socket/unix/transport/transport_message_list.go index 568cd5871..dda579c27 100644 --- a/pkg/sentry/socket/unix/transport/transport_message_list.go +++ b/pkg/sentry/socket/unix/transport/transport_message_list.go @@ -56,7 +56,7 @@ func (l *messageList) Back() *message { // // NOTE: This is an O(n) operation. func (l *messageList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (messageElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *messageList) Remove(e *message) { if prev != nil { messageElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { messageElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/socket/unix/transport/transport_state_autogen.go b/pkg/sentry/socket/unix/transport/transport_state_autogen.go index b47951498..4b88ea3ae 100644 --- a/pkg/sentry/socket/unix/transport/transport_state_autogen.go +++ b/pkg/sentry/socket/unix/transport/transport_state_autogen.go @@ -6,188 +6,345 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *connectionedEndpoint) StateTypeName() string { + return "pkg/sentry/socket/unix/transport.connectionedEndpoint" +} + +func (x *connectionedEndpoint) StateFields() []string { + return []string{ + "baseEndpoint", + "id", + "idGenerator", + "stype", + "acceptedChan", + } +} + func (x *connectionedEndpoint) beforeSave() {} -func (x *connectionedEndpoint) save(m state.Map) { + +func (x *connectionedEndpoint) StateSave(m state.Sink) { x.beforeSave() var acceptedChan []*connectionedEndpoint = x.saveAcceptedChan() - m.SaveValue("acceptedChan", acceptedChan) - m.Save("baseEndpoint", &x.baseEndpoint) - m.Save("id", &x.id) - m.Save("idGenerator", &x.idGenerator) - m.Save("stype", &x.stype) + m.SaveValue(4, acceptedChan) + m.Save(0, &x.baseEndpoint) + m.Save(1, &x.id) + m.Save(2, &x.idGenerator) + m.Save(3, &x.stype) } func (x *connectionedEndpoint) afterLoad() {} -func (x *connectionedEndpoint) load(m state.Map) { - m.Load("baseEndpoint", &x.baseEndpoint) - m.Load("id", &x.id) - m.Load("idGenerator", &x.idGenerator) - m.Load("stype", &x.stype) - m.LoadValue("acceptedChan", new([]*connectionedEndpoint), func(y interface{}) { x.loadAcceptedChan(y.([]*connectionedEndpoint)) }) + +func (x *connectionedEndpoint) StateLoad(m state.Source) { + m.Load(0, &x.baseEndpoint) + m.Load(1, &x.id) + m.Load(2, &x.idGenerator) + m.Load(3, &x.stype) + m.LoadValue(4, new([]*connectionedEndpoint), func(y interface{}) { x.loadAcceptedChan(y.([]*connectionedEndpoint)) }) +} + +func (x *connectionlessEndpoint) StateTypeName() string { + return "pkg/sentry/socket/unix/transport.connectionlessEndpoint" +} + +func (x *connectionlessEndpoint) StateFields() []string { + return []string{ + "baseEndpoint", + } } func (x *connectionlessEndpoint) beforeSave() {} -func (x *connectionlessEndpoint) save(m state.Map) { + +func (x *connectionlessEndpoint) StateSave(m state.Sink) { x.beforeSave() - m.Save("baseEndpoint", &x.baseEndpoint) + m.Save(0, &x.baseEndpoint) } func (x *connectionlessEndpoint) afterLoad() {} -func (x *connectionlessEndpoint) load(m state.Map) { - m.Load("baseEndpoint", &x.baseEndpoint) + +func (x *connectionlessEndpoint) StateLoad(m state.Source) { + m.Load(0, &x.baseEndpoint) +} + +func (x *queue) StateTypeName() string { + return "pkg/sentry/socket/unix/transport.queue" +} + +func (x *queue) StateFields() []string { + return []string{ + "AtomicRefCount", + "ReaderQueue", + "WriterQueue", + "closed", + "unread", + "used", + "limit", + "dataList", + } } func (x *queue) beforeSave() {} -func (x *queue) save(m state.Map) { + +func (x *queue) StateSave(m state.Sink) { x.beforeSave() - m.Save("AtomicRefCount", &x.AtomicRefCount) - m.Save("ReaderQueue", &x.ReaderQueue) - m.Save("WriterQueue", &x.WriterQueue) - m.Save("closed", &x.closed) - m.Save("unread", &x.unread) - m.Save("used", &x.used) - m.Save("limit", &x.limit) - m.Save("dataList", &x.dataList) + m.Save(0, &x.AtomicRefCount) + m.Save(1, &x.ReaderQueue) + m.Save(2, &x.WriterQueue) + m.Save(3, &x.closed) + m.Save(4, &x.unread) + m.Save(5, &x.used) + m.Save(6, &x.limit) + m.Save(7, &x.dataList) } func (x *queue) afterLoad() {} -func (x *queue) load(m state.Map) { - m.Load("AtomicRefCount", &x.AtomicRefCount) - m.Load("ReaderQueue", &x.ReaderQueue) - m.Load("WriterQueue", &x.WriterQueue) - m.Load("closed", &x.closed) - m.Load("unread", &x.unread) - m.Load("used", &x.used) - m.Load("limit", &x.limit) - m.Load("dataList", &x.dataList) + +func (x *queue) StateLoad(m state.Source) { + m.Load(0, &x.AtomicRefCount) + m.Load(1, &x.ReaderQueue) + m.Load(2, &x.WriterQueue) + m.Load(3, &x.closed) + m.Load(4, &x.unread) + m.Load(5, &x.used) + m.Load(6, &x.limit) + m.Load(7, &x.dataList) +} + +func (x *messageList) StateTypeName() string { + return "pkg/sentry/socket/unix/transport.messageList" +} + +func (x *messageList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *messageList) beforeSave() {} -func (x *messageList) save(m state.Map) { + +func (x *messageList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *messageList) afterLoad() {} -func (x *messageList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *messageList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *messageEntry) StateTypeName() string { + return "pkg/sentry/socket/unix/transport.messageEntry" +} + +func (x *messageEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *messageEntry) beforeSave() {} -func (x *messageEntry) save(m state.Map) { + +func (x *messageEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *messageEntry) afterLoad() {} -func (x *messageEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *messageEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) +} + +func (x *ControlMessages) StateTypeName() string { + return "pkg/sentry/socket/unix/transport.ControlMessages" +} + +func (x *ControlMessages) StateFields() []string { + return []string{ + "Rights", + "Credentials", + } } func (x *ControlMessages) beforeSave() {} -func (x *ControlMessages) save(m state.Map) { + +func (x *ControlMessages) StateSave(m state.Sink) { x.beforeSave() - m.Save("Rights", &x.Rights) - m.Save("Credentials", &x.Credentials) + m.Save(0, &x.Rights) + m.Save(1, &x.Credentials) } func (x *ControlMessages) afterLoad() {} -func (x *ControlMessages) load(m state.Map) { - m.Load("Rights", &x.Rights) - m.Load("Credentials", &x.Credentials) + +func (x *ControlMessages) StateLoad(m state.Source) { + m.Load(0, &x.Rights) + m.Load(1, &x.Credentials) +} + +func (x *message) StateTypeName() string { + return "pkg/sentry/socket/unix/transport.message" +} + +func (x *message) StateFields() []string { + return []string{ + "messageEntry", + "Data", + "Control", + "Address", + } } func (x *message) beforeSave() {} -func (x *message) save(m state.Map) { + +func (x *message) StateSave(m state.Sink) { x.beforeSave() - m.Save("messageEntry", &x.messageEntry) - m.Save("Data", &x.Data) - m.Save("Control", &x.Control) - m.Save("Address", &x.Address) + m.Save(0, &x.messageEntry) + m.Save(1, &x.Data) + m.Save(2, &x.Control) + m.Save(3, &x.Address) } func (x *message) afterLoad() {} -func (x *message) load(m state.Map) { - m.Load("messageEntry", &x.messageEntry) - m.Load("Data", &x.Data) - m.Load("Control", &x.Control) - m.Load("Address", &x.Address) + +func (x *message) StateLoad(m state.Source) { + m.Load(0, &x.messageEntry) + m.Load(1, &x.Data) + m.Load(2, &x.Control) + m.Load(3, &x.Address) +} + +func (x *queueReceiver) StateTypeName() string { + return "pkg/sentry/socket/unix/transport.queueReceiver" +} + +func (x *queueReceiver) StateFields() []string { + return []string{ + "readQueue", + } } func (x *queueReceiver) beforeSave() {} -func (x *queueReceiver) save(m state.Map) { + +func (x *queueReceiver) StateSave(m state.Sink) { x.beforeSave() - m.Save("readQueue", &x.readQueue) + m.Save(0, &x.readQueue) } func (x *queueReceiver) afterLoad() {} -func (x *queueReceiver) load(m state.Map) { - m.Load("readQueue", &x.readQueue) + +func (x *queueReceiver) StateLoad(m state.Source) { + m.Load(0, &x.readQueue) +} + +func (x *streamQueueReceiver) StateTypeName() string { + return "pkg/sentry/socket/unix/transport.streamQueueReceiver" +} + +func (x *streamQueueReceiver) StateFields() []string { + return []string{ + "queueReceiver", + "buffer", + "control", + "addr", + } } func (x *streamQueueReceiver) beforeSave() {} -func (x *streamQueueReceiver) save(m state.Map) { + +func (x *streamQueueReceiver) StateSave(m state.Sink) { x.beforeSave() - m.Save("queueReceiver", &x.queueReceiver) - m.Save("buffer", &x.buffer) - m.Save("control", &x.control) - m.Save("addr", &x.addr) + m.Save(0, &x.queueReceiver) + m.Save(1, &x.buffer) + m.Save(2, &x.control) + m.Save(3, &x.addr) } func (x *streamQueueReceiver) afterLoad() {} -func (x *streamQueueReceiver) load(m state.Map) { - m.Load("queueReceiver", &x.queueReceiver) - m.Load("buffer", &x.buffer) - m.Load("control", &x.control) - m.Load("addr", &x.addr) + +func (x *streamQueueReceiver) StateLoad(m state.Source) { + m.Load(0, &x.queueReceiver) + m.Load(1, &x.buffer) + m.Load(2, &x.control) + m.Load(3, &x.addr) +} + +func (x *connectedEndpoint) StateTypeName() string { + return "pkg/sentry/socket/unix/transport.connectedEndpoint" +} + +func (x *connectedEndpoint) StateFields() []string { + return []string{ + "endpoint", + "writeQueue", + } } func (x *connectedEndpoint) beforeSave() {} -func (x *connectedEndpoint) save(m state.Map) { + +func (x *connectedEndpoint) StateSave(m state.Sink) { x.beforeSave() - m.Save("endpoint", &x.endpoint) - m.Save("writeQueue", &x.writeQueue) + m.Save(0, &x.endpoint) + m.Save(1, &x.writeQueue) } func (x *connectedEndpoint) afterLoad() {} -func (x *connectedEndpoint) load(m state.Map) { - m.Load("endpoint", &x.endpoint) - m.Load("writeQueue", &x.writeQueue) + +func (x *connectedEndpoint) StateLoad(m state.Source) { + m.Load(0, &x.endpoint) + m.Load(1, &x.writeQueue) +} + +func (x *baseEndpoint) StateTypeName() string { + return "pkg/sentry/socket/unix/transport.baseEndpoint" +} + +func (x *baseEndpoint) StateFields() []string { + return []string{ + "Queue", + "passcred", + "receiver", + "connected", + "path", + } } func (x *baseEndpoint) beforeSave() {} -func (x *baseEndpoint) save(m state.Map) { + +func (x *baseEndpoint) StateSave(m state.Sink) { x.beforeSave() - m.Save("Queue", &x.Queue) - m.Save("passcred", &x.passcred) - m.Save("receiver", &x.receiver) - m.Save("connected", &x.connected) - m.Save("path", &x.path) + m.Save(0, &x.Queue) + m.Save(1, &x.passcred) + m.Save(2, &x.receiver) + m.Save(3, &x.connected) + m.Save(4, &x.path) } func (x *baseEndpoint) afterLoad() {} -func (x *baseEndpoint) load(m state.Map) { - m.Load("Queue", &x.Queue) - m.Load("passcred", &x.passcred) - m.Load("receiver", &x.receiver) - m.Load("connected", &x.connected) - m.Load("path", &x.path) + +func (x *baseEndpoint) StateLoad(m state.Source) { + m.Load(0, &x.Queue) + m.Load(1, &x.passcred) + m.Load(2, &x.receiver) + m.Load(3, &x.connected) + m.Load(4, &x.path) } func init() { - state.Register("pkg/sentry/socket/unix/transport.connectionedEndpoint", (*connectionedEndpoint)(nil), state.Fns{Save: (*connectionedEndpoint).save, Load: (*connectionedEndpoint).load}) - state.Register("pkg/sentry/socket/unix/transport.connectionlessEndpoint", (*connectionlessEndpoint)(nil), state.Fns{Save: (*connectionlessEndpoint).save, Load: (*connectionlessEndpoint).load}) - state.Register("pkg/sentry/socket/unix/transport.queue", (*queue)(nil), state.Fns{Save: (*queue).save, Load: (*queue).load}) - state.Register("pkg/sentry/socket/unix/transport.messageList", (*messageList)(nil), state.Fns{Save: (*messageList).save, Load: (*messageList).load}) - state.Register("pkg/sentry/socket/unix/transport.messageEntry", (*messageEntry)(nil), state.Fns{Save: (*messageEntry).save, Load: (*messageEntry).load}) - state.Register("pkg/sentry/socket/unix/transport.ControlMessages", (*ControlMessages)(nil), state.Fns{Save: (*ControlMessages).save, Load: (*ControlMessages).load}) - state.Register("pkg/sentry/socket/unix/transport.message", (*message)(nil), state.Fns{Save: (*message).save, Load: (*message).load}) - state.Register("pkg/sentry/socket/unix/transport.queueReceiver", (*queueReceiver)(nil), state.Fns{Save: (*queueReceiver).save, Load: (*queueReceiver).load}) - state.Register("pkg/sentry/socket/unix/transport.streamQueueReceiver", (*streamQueueReceiver)(nil), state.Fns{Save: (*streamQueueReceiver).save, Load: (*streamQueueReceiver).load}) - state.Register("pkg/sentry/socket/unix/transport.connectedEndpoint", (*connectedEndpoint)(nil), state.Fns{Save: (*connectedEndpoint).save, Load: (*connectedEndpoint).load}) - state.Register("pkg/sentry/socket/unix/transport.baseEndpoint", (*baseEndpoint)(nil), state.Fns{Save: (*baseEndpoint).save, Load: (*baseEndpoint).load}) + state.Register((*connectionedEndpoint)(nil)) + state.Register((*connectionlessEndpoint)(nil)) + state.Register((*queue)(nil)) + state.Register((*messageList)(nil)) + state.Register((*messageEntry)(nil)) + state.Register((*ControlMessages)(nil)) + state.Register((*message)(nil)) + state.Register((*queueReceiver)(nil)) + state.Register((*streamQueueReceiver)(nil)) + state.Register((*connectedEndpoint)(nil)) + state.Register((*baseEndpoint)(nil)) } diff --git a/pkg/sentry/socket/unix/unix_state_autogen.go b/pkg/sentry/socket/unix/unix_state_autogen.go index aa05e7b99..4a3bbc11b 100644 --- a/pkg/sentry/socket/unix/unix_state_autogen.go +++ b/pkg/sentry/socket/unix/unix_state_autogen.go @@ -6,35 +6,62 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *SocketOperations) StateTypeName() string { + return "pkg/sentry/socket/unix.SocketOperations" +} + +func (x *SocketOperations) StateFields() []string { + return []string{ + "socketOpsCommon", + } +} + func (x *SocketOperations) beforeSave() {} -func (x *SocketOperations) save(m state.Map) { + +func (x *SocketOperations) StateSave(m state.Sink) { x.beforeSave() - m.Save("socketOpsCommon", &x.socketOpsCommon) + m.Save(0, &x.socketOpsCommon) } func (x *SocketOperations) afterLoad() {} -func (x *SocketOperations) load(m state.Map) { - m.Load("socketOpsCommon", &x.socketOpsCommon) + +func (x *SocketOperations) StateLoad(m state.Source) { + m.Load(0, &x.socketOpsCommon) +} + +func (x *socketOpsCommon) StateTypeName() string { + return "pkg/sentry/socket/unix.socketOpsCommon" +} + +func (x *socketOpsCommon) StateFields() []string { + return []string{ + "AtomicRefCount", + "SendReceiveTimeout", + "ep", + "stype", + } } func (x *socketOpsCommon) beforeSave() {} -func (x *socketOpsCommon) save(m state.Map) { + +func (x *socketOpsCommon) StateSave(m state.Sink) { x.beforeSave() - m.Save("AtomicRefCount", &x.AtomicRefCount) - m.Save("SendReceiveTimeout", &x.SendReceiveTimeout) - m.Save("ep", &x.ep) - m.Save("stype", &x.stype) + m.Save(0, &x.AtomicRefCount) + m.Save(1, &x.SendReceiveTimeout) + m.Save(2, &x.ep) + m.Save(3, &x.stype) } func (x *socketOpsCommon) afterLoad() {} -func (x *socketOpsCommon) load(m state.Map) { - m.Load("AtomicRefCount", &x.AtomicRefCount) - m.Load("SendReceiveTimeout", &x.SendReceiveTimeout) - m.Load("ep", &x.ep) - m.Load("stype", &x.stype) + +func (x *socketOpsCommon) StateLoad(m state.Source) { + m.Load(0, &x.AtomicRefCount) + m.Load(1, &x.SendReceiveTimeout) + m.Load(2, &x.ep) + m.Load(3, &x.stype) } func init() { - state.Register("pkg/sentry/socket/unix.SocketOperations", (*SocketOperations)(nil), state.Fns{Save: (*SocketOperations).save, Load: (*SocketOperations).load}) - state.Register("pkg/sentry/socket/unix.socketOpsCommon", (*socketOpsCommon)(nil), state.Fns{Save: (*socketOpsCommon).save, Load: (*socketOpsCommon).load}) + state.Register((*SocketOperations)(nil)) + state.Register((*socketOpsCommon)(nil)) } diff --git a/pkg/sentry/syscalls/linux/linux_state_autogen.go b/pkg/sentry/syscalls/linux/linux_state_autogen.go index c76ccd1d5..8d70a3ee6 100644 --- a/pkg/sentry/syscalls/linux/linux_state_autogen.go +++ b/pkg/sentry/syscalls/linux/linux_state_autogen.go @@ -6,57 +6,101 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *futexWaitRestartBlock) StateTypeName() string { + return "pkg/sentry/syscalls/linux.futexWaitRestartBlock" +} + +func (x *futexWaitRestartBlock) StateFields() []string { + return []string{ + "duration", + "addr", + "private", + "val", + "mask", + } +} + func (x *futexWaitRestartBlock) beforeSave() {} -func (x *futexWaitRestartBlock) save(m state.Map) { + +func (x *futexWaitRestartBlock) StateSave(m state.Sink) { x.beforeSave() - m.Save("duration", &x.duration) - m.Save("addr", &x.addr) - m.Save("private", &x.private) - m.Save("val", &x.val) - m.Save("mask", &x.mask) + m.Save(0, &x.duration) + m.Save(1, &x.addr) + m.Save(2, &x.private) + m.Save(3, &x.val) + m.Save(4, &x.mask) } func (x *futexWaitRestartBlock) afterLoad() {} -func (x *futexWaitRestartBlock) load(m state.Map) { - m.Load("duration", &x.duration) - m.Load("addr", &x.addr) - m.Load("private", &x.private) - m.Load("val", &x.val) - m.Load("mask", &x.mask) + +func (x *futexWaitRestartBlock) StateLoad(m state.Source) { + m.Load(0, &x.duration) + m.Load(1, &x.addr) + m.Load(2, &x.private) + m.Load(3, &x.val) + m.Load(4, &x.mask) +} + +func (x *pollRestartBlock) StateTypeName() string { + return "pkg/sentry/syscalls/linux.pollRestartBlock" +} + +func (x *pollRestartBlock) StateFields() []string { + return []string{ + "pfdAddr", + "nfds", + "timeout", + } } func (x *pollRestartBlock) beforeSave() {} -func (x *pollRestartBlock) save(m state.Map) { + +func (x *pollRestartBlock) StateSave(m state.Sink) { x.beforeSave() - m.Save("pfdAddr", &x.pfdAddr) - m.Save("nfds", &x.nfds) - m.Save("timeout", &x.timeout) + m.Save(0, &x.pfdAddr) + m.Save(1, &x.nfds) + m.Save(2, &x.timeout) } func (x *pollRestartBlock) afterLoad() {} -func (x *pollRestartBlock) load(m state.Map) { - m.Load("pfdAddr", &x.pfdAddr) - m.Load("nfds", &x.nfds) - m.Load("timeout", &x.timeout) + +func (x *pollRestartBlock) StateLoad(m state.Source) { + m.Load(0, &x.pfdAddr) + m.Load(1, &x.nfds) + m.Load(2, &x.timeout) +} + +func (x *clockNanosleepRestartBlock) StateTypeName() string { + return "pkg/sentry/syscalls/linux.clockNanosleepRestartBlock" +} + +func (x *clockNanosleepRestartBlock) StateFields() []string { + return []string{ + "c", + "duration", + "rem", + } } func (x *clockNanosleepRestartBlock) beforeSave() {} -func (x *clockNanosleepRestartBlock) save(m state.Map) { + +func (x *clockNanosleepRestartBlock) StateSave(m state.Sink) { x.beforeSave() - m.Save("c", &x.c) - m.Save("duration", &x.duration) - m.Save("rem", &x.rem) + m.Save(0, &x.c) + m.Save(1, &x.duration) + m.Save(2, &x.rem) } func (x *clockNanosleepRestartBlock) afterLoad() {} -func (x *clockNanosleepRestartBlock) load(m state.Map) { - m.Load("c", &x.c) - m.Load("duration", &x.duration) - m.Load("rem", &x.rem) + +func (x *clockNanosleepRestartBlock) StateLoad(m state.Source) { + m.Load(0, &x.c) + m.Load(1, &x.duration) + m.Load(2, &x.rem) } func init() { - state.Register("pkg/sentry/syscalls/linux.futexWaitRestartBlock", (*futexWaitRestartBlock)(nil), state.Fns{Save: (*futexWaitRestartBlock).save, Load: (*futexWaitRestartBlock).load}) - state.Register("pkg/sentry/syscalls/linux.pollRestartBlock", (*pollRestartBlock)(nil), state.Fns{Save: (*pollRestartBlock).save, Load: (*pollRestartBlock).load}) - state.Register("pkg/sentry/syscalls/linux.clockNanosleepRestartBlock", (*clockNanosleepRestartBlock)(nil), state.Fns{Save: (*clockNanosleepRestartBlock).save, Load: (*clockNanosleepRestartBlock).load}) + state.Register((*futexWaitRestartBlock)(nil)) + state.Register((*pollRestartBlock)(nil)) + state.Register((*clockNanosleepRestartBlock)(nil)) } diff --git a/pkg/sentry/syscalls/linux/vfs2/vfs2_state_autogen.go b/pkg/sentry/syscalls/linux/vfs2/vfs2_state_autogen.go index 570100331..031381834 100644 --- a/pkg/sentry/syscalls/linux/vfs2/vfs2_state_autogen.go +++ b/pkg/sentry/syscalls/linux/vfs2/vfs2_state_autogen.go @@ -6,21 +6,35 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *pollRestartBlock) StateTypeName() string { + return "pkg/sentry/syscalls/linux/vfs2.pollRestartBlock" +} + +func (x *pollRestartBlock) StateFields() []string { + return []string{ + "pfdAddr", + "nfds", + "timeout", + } +} + func (x *pollRestartBlock) beforeSave() {} -func (x *pollRestartBlock) save(m state.Map) { + +func (x *pollRestartBlock) StateSave(m state.Sink) { x.beforeSave() - m.Save("pfdAddr", &x.pfdAddr) - m.Save("nfds", &x.nfds) - m.Save("timeout", &x.timeout) + m.Save(0, &x.pfdAddr) + m.Save(1, &x.nfds) + m.Save(2, &x.timeout) } func (x *pollRestartBlock) afterLoad() {} -func (x *pollRestartBlock) load(m state.Map) { - m.Load("pfdAddr", &x.pfdAddr) - m.Load("nfds", &x.nfds) - m.Load("timeout", &x.timeout) + +func (x *pollRestartBlock) StateLoad(m state.Source) { + m.Load(0, &x.pfdAddr) + m.Load(1, &x.nfds) + m.Load(2, &x.timeout) } func init() { - state.Register("pkg/sentry/syscalls/linux/vfs2.pollRestartBlock", (*pollRestartBlock)(nil), state.Fns{Save: (*pollRestartBlock).save, Load: (*pollRestartBlock).load}) + state.Register((*pollRestartBlock)(nil)) } diff --git a/pkg/sentry/usage/usage_state_autogen.go b/pkg/sentry/usage/usage_state_autogen.go index 42979ea25..a117ad216 100644 --- a/pkg/sentry/usage/usage_state_autogen.go +++ b/pkg/sentry/usage/usage_state_autogen.go @@ -6,45 +6,77 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *CPUStats) StateTypeName() string { + return "pkg/sentry/usage.CPUStats" +} + +func (x *CPUStats) StateFields() []string { + return []string{ + "UserTime", + "SysTime", + "VoluntarySwitches", + } +} + func (x *CPUStats) beforeSave() {} -func (x *CPUStats) save(m state.Map) { + +func (x *CPUStats) StateSave(m state.Sink) { x.beforeSave() - m.Save("UserTime", &x.UserTime) - m.Save("SysTime", &x.SysTime) - m.Save("VoluntarySwitches", &x.VoluntarySwitches) + m.Save(0, &x.UserTime) + m.Save(1, &x.SysTime) + m.Save(2, &x.VoluntarySwitches) } func (x *CPUStats) afterLoad() {} -func (x *CPUStats) load(m state.Map) { - m.Load("UserTime", &x.UserTime) - m.Load("SysTime", &x.SysTime) - m.Load("VoluntarySwitches", &x.VoluntarySwitches) + +func (x *CPUStats) StateLoad(m state.Source) { + m.Load(0, &x.UserTime) + m.Load(1, &x.SysTime) + m.Load(2, &x.VoluntarySwitches) +} + +func (x *IO) StateTypeName() string { + return "pkg/sentry/usage.IO" +} + +func (x *IO) StateFields() []string { + return []string{ + "CharsRead", + "CharsWritten", + "ReadSyscalls", + "WriteSyscalls", + "BytesRead", + "BytesWritten", + "BytesWriteCancelled", + } } func (x *IO) beforeSave() {} -func (x *IO) save(m state.Map) { + +func (x *IO) StateSave(m state.Sink) { x.beforeSave() - m.Save("CharsRead", &x.CharsRead) - m.Save("CharsWritten", &x.CharsWritten) - m.Save("ReadSyscalls", &x.ReadSyscalls) - m.Save("WriteSyscalls", &x.WriteSyscalls) - m.Save("BytesRead", &x.BytesRead) - m.Save("BytesWritten", &x.BytesWritten) - m.Save("BytesWriteCancelled", &x.BytesWriteCancelled) + m.Save(0, &x.CharsRead) + m.Save(1, &x.CharsWritten) + m.Save(2, &x.ReadSyscalls) + m.Save(3, &x.WriteSyscalls) + m.Save(4, &x.BytesRead) + m.Save(5, &x.BytesWritten) + m.Save(6, &x.BytesWriteCancelled) } func (x *IO) afterLoad() {} -func (x *IO) load(m state.Map) { - m.Load("CharsRead", &x.CharsRead) - m.Load("CharsWritten", &x.CharsWritten) - m.Load("ReadSyscalls", &x.ReadSyscalls) - m.Load("WriteSyscalls", &x.WriteSyscalls) - m.Load("BytesRead", &x.BytesRead) - m.Load("BytesWritten", &x.BytesWritten) - m.Load("BytesWriteCancelled", &x.BytesWriteCancelled) + +func (x *IO) StateLoad(m state.Source) { + m.Load(0, &x.CharsRead) + m.Load(1, &x.CharsWritten) + m.Load(2, &x.ReadSyscalls) + m.Load(3, &x.WriteSyscalls) + m.Load(4, &x.BytesRead) + m.Load(5, &x.BytesWritten) + m.Load(6, &x.BytesWriteCancelled) } func init() { - state.Register("pkg/sentry/usage.CPUStats", (*CPUStats)(nil), state.Fns{Save: (*CPUStats).save, Load: (*CPUStats).load}) - state.Register("pkg/sentry/usage.IO", (*IO)(nil), state.Fns{Save: (*IO).save, Load: (*IO).load}) + state.Register((*CPUStats)(nil)) + state.Register((*IO)(nil)) } diff --git a/pkg/sentry/vfs/epoll_interest_list.go b/pkg/sentry/vfs/epoll_interest_list.go index 67104a9c6..ad8ae496a 100644 --- a/pkg/sentry/vfs/epoll_interest_list.go +++ b/pkg/sentry/vfs/epoll_interest_list.go @@ -56,7 +56,7 @@ func (l *epollInterestList) Back() *epollInterest { // // NOTE: This is an O(n) operation. func (l *epollInterestList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (epollInterestElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *epollInterestList) Remove(e *epollInterest) { if prev != nil { epollInterestElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { epollInterestElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/vfs/event_list.go b/pkg/sentry/vfs/event_list.go index 2ae5b6aba..ebfb272fd 100644 --- a/pkg/sentry/vfs/event_list.go +++ b/pkg/sentry/vfs/event_list.go @@ -56,7 +56,7 @@ func (l *eventList) Back() *Event { // // NOTE: This is an O(n) operation. func (l *eventList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (eventElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *eventList) Remove(e *Event) { if prev != nil { eventElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { eventElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/sentry/vfs/memxattr/memxattr_state_autogen.go b/pkg/sentry/vfs/memxattr/memxattr_state_autogen.go index 6b366cea4..105af5cb5 100644 --- a/pkg/sentry/vfs/memxattr/memxattr_state_autogen.go +++ b/pkg/sentry/vfs/memxattr/memxattr_state_autogen.go @@ -6,17 +6,29 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *SimpleExtendedAttributes) StateTypeName() string { + return "pkg/sentry/vfs/memxattr.SimpleExtendedAttributes" +} + +func (x *SimpleExtendedAttributes) StateFields() []string { + return []string{ + "xattrs", + } +} + func (x *SimpleExtendedAttributes) beforeSave() {} -func (x *SimpleExtendedAttributes) save(m state.Map) { + +func (x *SimpleExtendedAttributes) StateSave(m state.Sink) { x.beforeSave() - m.Save("xattrs", &x.xattrs) + m.Save(0, &x.xattrs) } func (x *SimpleExtendedAttributes) afterLoad() {} -func (x *SimpleExtendedAttributes) load(m state.Map) { - m.Load("xattrs", &x.xattrs) + +func (x *SimpleExtendedAttributes) StateLoad(m state.Source) { + m.Load(0, &x.xattrs) } func init() { - state.Register("pkg/sentry/vfs/memxattr.SimpleExtendedAttributes", (*SimpleExtendedAttributes)(nil), state.Fns{Save: (*SimpleExtendedAttributes).save, Load: (*SimpleExtendedAttributes).load}) + state.Register((*SimpleExtendedAttributes)(nil)) } diff --git a/pkg/sentry/vfs/vfs_state_autogen.go b/pkg/sentry/vfs/vfs_state_autogen.go index be27d746f..c1f514db4 100644 --- a/pkg/sentry/vfs/vfs_state_autogen.go +++ b/pkg/sentry/vfs/vfs_state_autogen.go @@ -6,307 +6,560 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *Dentry) StateTypeName() string { + return "pkg/sentry/vfs.Dentry" +} + +func (x *Dentry) StateFields() []string { + return []string{ + "dead", + "mounts", + "impl", + } +} + func (x *Dentry) beforeSave() {} -func (x *Dentry) save(m state.Map) { + +func (x *Dentry) StateSave(m state.Sink) { x.beforeSave() - m.Save("dead", &x.dead) - m.Save("mounts", &x.mounts) - m.Save("impl", &x.impl) + m.Save(0, &x.dead) + m.Save(1, &x.mounts) + m.Save(2, &x.impl) } func (x *Dentry) afterLoad() {} -func (x *Dentry) load(m state.Map) { - m.Load("dead", &x.dead) - m.Load("mounts", &x.mounts) - m.Load("impl", &x.impl) + +func (x *Dentry) StateLoad(m state.Source) { + m.Load(0, &x.dead) + m.Load(1, &x.mounts) + m.Load(2, &x.impl) +} + +func (x *registeredDevice) StateTypeName() string { + return "pkg/sentry/vfs.registeredDevice" +} + +func (x *registeredDevice) StateFields() []string { + return []string{ + "dev", + "opts", + } } func (x *registeredDevice) beforeSave() {} -func (x *registeredDevice) save(m state.Map) { + +func (x *registeredDevice) StateSave(m state.Sink) { x.beforeSave() - m.Save("dev", &x.dev) - m.Save("opts", &x.opts) + m.Save(0, &x.dev) + m.Save(1, &x.opts) } func (x *registeredDevice) afterLoad() {} -func (x *registeredDevice) load(m state.Map) { - m.Load("dev", &x.dev) - m.Load("opts", &x.opts) + +func (x *registeredDevice) StateLoad(m state.Source) { + m.Load(0, &x.dev) + m.Load(1, &x.opts) +} + +func (x *RegisterDeviceOptions) StateTypeName() string { + return "pkg/sentry/vfs.RegisterDeviceOptions" +} + +func (x *RegisterDeviceOptions) StateFields() []string { + return []string{ + "GroupName", + } } func (x *RegisterDeviceOptions) beforeSave() {} -func (x *RegisterDeviceOptions) save(m state.Map) { + +func (x *RegisterDeviceOptions) StateSave(m state.Sink) { x.beforeSave() - m.Save("GroupName", &x.GroupName) + m.Save(0, &x.GroupName) } func (x *RegisterDeviceOptions) afterLoad() {} -func (x *RegisterDeviceOptions) load(m state.Map) { - m.Load("GroupName", &x.GroupName) + +func (x *RegisterDeviceOptions) StateLoad(m state.Source) { + m.Load(0, &x.GroupName) +} + +func (x *epollInterestList) StateTypeName() string { + return "pkg/sentry/vfs.epollInterestList" +} + +func (x *epollInterestList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *epollInterestList) beforeSave() {} -func (x *epollInterestList) save(m state.Map) { + +func (x *epollInterestList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *epollInterestList) afterLoad() {} -func (x *epollInterestList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *epollInterestList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *epollInterestEntry) StateTypeName() string { + return "pkg/sentry/vfs.epollInterestEntry" +} + +func (x *epollInterestEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *epollInterestEntry) beforeSave() {} -func (x *epollInterestEntry) save(m state.Map) { + +func (x *epollInterestEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *epollInterestEntry) afterLoad() {} -func (x *epollInterestEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *epollInterestEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) +} + +func (x *eventList) StateTypeName() string { + return "pkg/sentry/vfs.eventList" +} + +func (x *eventList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *eventList) beforeSave() {} -func (x *eventList) save(m state.Map) { + +func (x *eventList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *eventList) afterLoad() {} -func (x *eventList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *eventList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *eventEntry) StateTypeName() string { + return "pkg/sentry/vfs.eventEntry" +} + +func (x *eventEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *eventEntry) beforeSave() {} -func (x *eventEntry) save(m state.Map) { + +func (x *eventEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *eventEntry) afterLoad() {} -func (x *eventEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *eventEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) +} + +func (x *Filesystem) StateTypeName() string { + return "pkg/sentry/vfs.Filesystem" +} + +func (x *Filesystem) StateFields() []string { + return []string{ + "refs", + "vfs", + "fsType", + "impl", + } } func (x *Filesystem) beforeSave() {} -func (x *Filesystem) save(m state.Map) { + +func (x *Filesystem) StateSave(m state.Sink) { x.beforeSave() - m.Save("refs", &x.refs) - m.Save("vfs", &x.vfs) - m.Save("fsType", &x.fsType) - m.Save("impl", &x.impl) + m.Save(0, &x.refs) + m.Save(1, &x.vfs) + m.Save(2, &x.fsType) + m.Save(3, &x.impl) } func (x *Filesystem) afterLoad() {} -func (x *Filesystem) load(m state.Map) { - m.Load("refs", &x.refs) - m.Load("vfs", &x.vfs) - m.Load("fsType", &x.fsType) - m.Load("impl", &x.impl) + +func (x *Filesystem) StateLoad(m state.Source) { + m.Load(0, &x.refs) + m.Load(1, &x.vfs) + m.Load(2, &x.fsType) + m.Load(3, &x.impl) +} + +func (x *registeredFilesystemType) StateTypeName() string { + return "pkg/sentry/vfs.registeredFilesystemType" +} + +func (x *registeredFilesystemType) StateFields() []string { + return []string{ + "fsType", + "opts", + } } func (x *registeredFilesystemType) beforeSave() {} -func (x *registeredFilesystemType) save(m state.Map) { + +func (x *registeredFilesystemType) StateSave(m state.Sink) { x.beforeSave() - m.Save("fsType", &x.fsType) - m.Save("opts", &x.opts) + m.Save(0, &x.fsType) + m.Save(1, &x.opts) } func (x *registeredFilesystemType) afterLoad() {} -func (x *registeredFilesystemType) load(m state.Map) { - m.Load("fsType", &x.fsType) - m.Load("opts", &x.opts) + +func (x *registeredFilesystemType) StateLoad(m state.Source) { + m.Load(0, &x.fsType) + m.Load(1, &x.opts) +} + +func (x *Inotify) StateTypeName() string { + return "pkg/sentry/vfs.Inotify" +} + +func (x *Inotify) StateFields() []string { + return []string{ + "vfsfd", + "FileDescriptionDefaultImpl", + "DentryMetadataFileDescriptionImpl", + "NoLockFD", + "id", + "events", + "scratch", + "nextWatchMinusOne", + "watches", + } } func (x *Inotify) beforeSave() {} -func (x *Inotify) save(m state.Map) { + +func (x *Inotify) StateSave(m state.Sink) { x.beforeSave() - m.Save("vfsfd", &x.vfsfd) - m.Save("FileDescriptionDefaultImpl", &x.FileDescriptionDefaultImpl) - m.Save("DentryMetadataFileDescriptionImpl", &x.DentryMetadataFileDescriptionImpl) - m.Save("NoLockFD", &x.NoLockFD) - m.Save("id", &x.id) - m.Save("events", &x.events) - m.Save("scratch", &x.scratch) - m.Save("nextWatchMinusOne", &x.nextWatchMinusOne) - m.Save("watches", &x.watches) + m.Save(0, &x.vfsfd) + m.Save(1, &x.FileDescriptionDefaultImpl) + m.Save(2, &x.DentryMetadataFileDescriptionImpl) + m.Save(3, &x.NoLockFD) + m.Save(4, &x.id) + m.Save(5, &x.events) + m.Save(6, &x.scratch) + m.Save(7, &x.nextWatchMinusOne) + m.Save(8, &x.watches) } func (x *Inotify) afterLoad() {} -func (x *Inotify) load(m state.Map) { - m.Load("vfsfd", &x.vfsfd) - m.Load("FileDescriptionDefaultImpl", &x.FileDescriptionDefaultImpl) - m.Load("DentryMetadataFileDescriptionImpl", &x.DentryMetadataFileDescriptionImpl) - m.Load("NoLockFD", &x.NoLockFD) - m.Load("id", &x.id) - m.Load("events", &x.events) - m.Load("scratch", &x.scratch) - m.Load("nextWatchMinusOne", &x.nextWatchMinusOne) - m.Load("watches", &x.watches) + +func (x *Inotify) 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.id) + m.Load(5, &x.events) + m.Load(6, &x.scratch) + m.Load(7, &x.nextWatchMinusOne) + m.Load(8, &x.watches) +} + +func (x *Watches) StateTypeName() string { + return "pkg/sentry/vfs.Watches" +} + +func (x *Watches) StateFields() []string { + return []string{ + "ws", + } } func (x *Watches) beforeSave() {} -func (x *Watches) save(m state.Map) { + +func (x *Watches) StateSave(m state.Sink) { x.beforeSave() - m.Save("ws", &x.ws) + m.Save(0, &x.ws) } func (x *Watches) afterLoad() {} -func (x *Watches) load(m state.Map) { - m.Load("ws", &x.ws) + +func (x *Watches) StateLoad(m state.Source) { + m.Load(0, &x.ws) +} + +func (x *Watch) StateTypeName() string { + return "pkg/sentry/vfs.Watch" +} + +func (x *Watch) StateFields() []string { + return []string{ + "owner", + "wd", + "target", + "mask", + } } func (x *Watch) beforeSave() {} -func (x *Watch) save(m state.Map) { + +func (x *Watch) StateSave(m state.Sink) { x.beforeSave() - m.Save("owner", &x.owner) - m.Save("wd", &x.wd) - m.Save("target", &x.target) - m.Save("mask", &x.mask) + m.Save(0, &x.owner) + m.Save(1, &x.wd) + m.Save(2, &x.target) + m.Save(3, &x.mask) } func (x *Watch) afterLoad() {} -func (x *Watch) load(m state.Map) { - m.Load("owner", &x.owner) - m.Load("wd", &x.wd) - m.Load("target", &x.target) - m.Load("mask", &x.mask) + +func (x *Watch) StateLoad(m state.Source) { + m.Load(0, &x.owner) + m.Load(1, &x.wd) + m.Load(2, &x.target) + m.Load(3, &x.mask) +} + +func (x *Event) StateTypeName() string { + return "pkg/sentry/vfs.Event" +} + +func (x *Event) StateFields() []string { + return []string{ + "eventEntry", + "wd", + "mask", + "cookie", + "len", + "name", + } } func (x *Event) beforeSave() {} -func (x *Event) save(m state.Map) { + +func (x *Event) StateSave(m state.Sink) { x.beforeSave() - m.Save("eventEntry", &x.eventEntry) - m.Save("wd", &x.wd) - m.Save("mask", &x.mask) - m.Save("cookie", &x.cookie) - m.Save("len", &x.len) - m.Save("name", &x.name) + m.Save(0, &x.eventEntry) + m.Save(1, &x.wd) + m.Save(2, &x.mask) + m.Save(3, &x.cookie) + m.Save(4, &x.len) + m.Save(5, &x.name) } func (x *Event) afterLoad() {} -func (x *Event) load(m state.Map) { - m.Load("eventEntry", &x.eventEntry) - m.Load("wd", &x.wd) - m.Load("mask", &x.mask) - m.Load("cookie", &x.cookie) - m.Load("len", &x.len) - m.Load("name", &x.name) + +func (x *Event) StateLoad(m state.Source) { + m.Load(0, &x.eventEntry) + m.Load(1, &x.wd) + m.Load(2, &x.mask) + m.Load(3, &x.cookie) + m.Load(4, &x.len) + m.Load(5, &x.name) +} + +func (x *Mount) StateTypeName() string { + return "pkg/sentry/vfs.Mount" +} + +func (x *Mount) StateFields() []string { + return []string{ + "vfs", + "fs", + "root", + "ID", + "Flags", + "key", + "ns", + "refs", + "children", + "umounted", + "writers", + } } func (x *Mount) beforeSave() {} -func (x *Mount) save(m state.Map) { + +func (x *Mount) StateSave(m state.Sink) { x.beforeSave() - m.Save("vfs", &x.vfs) - m.Save("fs", &x.fs) - m.Save("root", &x.root) - m.Save("ID", &x.ID) - m.Save("Flags", &x.Flags) - m.Save("key", &x.key) - m.Save("ns", &x.ns) - m.Save("refs", &x.refs) - m.Save("children", &x.children) - m.Save("umounted", &x.umounted) - m.Save("writers", &x.writers) + 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) + m.Save(9, &x.umounted) + m.Save(10, &x.writers) } func (x *Mount) afterLoad() {} -func (x *Mount) load(m state.Map) { - m.Load("vfs", &x.vfs) - m.Load("fs", &x.fs) - m.Load("root", &x.root) - m.Load("ID", &x.ID) - m.Load("Flags", &x.Flags) - m.Load("key", &x.key) - m.Load("ns", &x.ns) - m.Load("refs", &x.refs) - m.Load("children", &x.children) - m.Load("umounted", &x.umounted) - m.Load("writers", &x.writers) + +func (x *Mount) StateLoad(m state.Source) { + m.Load(0, &x.vfs) + m.Load(1, &x.fs) + 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) +} + +func (x *MountNamespace) StateTypeName() string { + return "pkg/sentry/vfs.MountNamespace" +} + +func (x *MountNamespace) StateFields() []string { + return []string{ + "Owner", + "root", + "refs", + "mountpoints", + } } func (x *MountNamespace) beforeSave() {} -func (x *MountNamespace) save(m state.Map) { + +func (x *MountNamespace) StateSave(m state.Sink) { x.beforeSave() - m.Save("Owner", &x.Owner) - m.Save("root", &x.root) - m.Save("refs", &x.refs) - m.Save("mountpoints", &x.mountpoints) + m.Save(0, &x.Owner) + m.Save(1, &x.root) + m.Save(2, &x.refs) + m.Save(3, &x.mountpoints) } func (x *MountNamespace) afterLoad() {} -func (x *MountNamespace) load(m state.Map) { - m.Load("Owner", &x.Owner) - m.Load("root", &x.root) - m.Load("refs", &x.refs) - m.Load("mountpoints", &x.mountpoints) + +func (x *MountNamespace) StateLoad(m state.Source) { + m.Load(0, &x.Owner) + m.Load(1, &x.root) + m.Load(2, &x.refs) + m.Load(3, &x.mountpoints) +} + +func (x *VirtualFilesystem) StateTypeName() string { + return "pkg/sentry/vfs.VirtualFilesystem" +} + +func (x *VirtualFilesystem) StateFields() []string { + return []string{ + "mounts", + "mountpoints", + "lastMountID", + "anonMount", + "devices", + "anonBlockDevMinorNext", + "anonBlockDevMinor", + "fsTypes", + "filesystems", + } } func (x *VirtualFilesystem) beforeSave() {} -func (x *VirtualFilesystem) save(m state.Map) { + +func (x *VirtualFilesystem) StateSave(m state.Sink) { x.beforeSave() - m.Save("mounts", &x.mounts) - m.Save("mountpoints", &x.mountpoints) - m.Save("lastMountID", &x.lastMountID) - m.Save("anonMount", &x.anonMount) - m.Save("devices", &x.devices) - m.Save("anonBlockDevMinorNext", &x.anonBlockDevMinorNext) - m.Save("anonBlockDevMinor", &x.anonBlockDevMinor) - m.Save("fsTypes", &x.fsTypes) - m.Save("filesystems", &x.filesystems) + m.Save(0, &x.mounts) + m.Save(1, &x.mountpoints) + m.Save(2, &x.lastMountID) + m.Save(3, &x.anonMount) + m.Save(4, &x.devices) + m.Save(5, &x.anonBlockDevMinorNext) + m.Save(6, &x.anonBlockDevMinor) + m.Save(7, &x.fsTypes) + m.Save(8, &x.filesystems) } func (x *VirtualFilesystem) afterLoad() {} -func (x *VirtualFilesystem) load(m state.Map) { - m.Load("mounts", &x.mounts) - m.Load("mountpoints", &x.mountpoints) - m.Load("lastMountID", &x.lastMountID) - m.Load("anonMount", &x.anonMount) - m.Load("devices", &x.devices) - m.Load("anonBlockDevMinorNext", &x.anonBlockDevMinorNext) - m.Load("anonBlockDevMinor", &x.anonBlockDevMinor) - m.Load("fsTypes", &x.fsTypes) - m.Load("filesystems", &x.filesystems) + +func (x *VirtualFilesystem) StateLoad(m state.Source) { + m.Load(0, &x.mounts) + m.Load(1, &x.mountpoints) + m.Load(2, &x.lastMountID) + m.Load(3, &x.anonMount) + m.Load(4, &x.devices) + m.Load(5, &x.anonBlockDevMinorNext) + m.Load(6, &x.anonBlockDevMinor) + m.Load(7, &x.fsTypes) + m.Load(8, &x.filesystems) +} + +func (x *VirtualDentry) StateTypeName() string { + return "pkg/sentry/vfs.VirtualDentry" +} + +func (x *VirtualDentry) StateFields() []string { + return []string{ + "mount", + "dentry", + } } func (x *VirtualDentry) beforeSave() {} -func (x *VirtualDentry) save(m state.Map) { + +func (x *VirtualDentry) StateSave(m state.Sink) { x.beforeSave() - m.Save("mount", &x.mount) - m.Save("dentry", &x.dentry) + m.Save(0, &x.mount) + m.Save(1, &x.dentry) } func (x *VirtualDentry) afterLoad() {} -func (x *VirtualDentry) load(m state.Map) { - m.Load("mount", &x.mount) - m.Load("dentry", &x.dentry) + +func (x *VirtualDentry) StateLoad(m state.Source) { + m.Load(0, &x.mount) + m.Load(1, &x.dentry) } func init() { - state.Register("pkg/sentry/vfs.Dentry", (*Dentry)(nil), state.Fns{Save: (*Dentry).save, Load: (*Dentry).load}) - state.Register("pkg/sentry/vfs.registeredDevice", (*registeredDevice)(nil), state.Fns{Save: (*registeredDevice).save, Load: (*registeredDevice).load}) - state.Register("pkg/sentry/vfs.RegisterDeviceOptions", (*RegisterDeviceOptions)(nil), state.Fns{Save: (*RegisterDeviceOptions).save, Load: (*RegisterDeviceOptions).load}) - state.Register("pkg/sentry/vfs.epollInterestList", (*epollInterestList)(nil), state.Fns{Save: (*epollInterestList).save, Load: (*epollInterestList).load}) - state.Register("pkg/sentry/vfs.epollInterestEntry", (*epollInterestEntry)(nil), state.Fns{Save: (*epollInterestEntry).save, Load: (*epollInterestEntry).load}) - state.Register("pkg/sentry/vfs.eventList", (*eventList)(nil), state.Fns{Save: (*eventList).save, Load: (*eventList).load}) - state.Register("pkg/sentry/vfs.eventEntry", (*eventEntry)(nil), state.Fns{Save: (*eventEntry).save, Load: (*eventEntry).load}) - state.Register("pkg/sentry/vfs.Filesystem", (*Filesystem)(nil), state.Fns{Save: (*Filesystem).save, Load: (*Filesystem).load}) - state.Register("pkg/sentry/vfs.registeredFilesystemType", (*registeredFilesystemType)(nil), state.Fns{Save: (*registeredFilesystemType).save, Load: (*registeredFilesystemType).load}) - state.Register("pkg/sentry/vfs.Inotify", (*Inotify)(nil), state.Fns{Save: (*Inotify).save, Load: (*Inotify).load}) - state.Register("pkg/sentry/vfs.Watches", (*Watches)(nil), state.Fns{Save: (*Watches).save, Load: (*Watches).load}) - state.Register("pkg/sentry/vfs.Watch", (*Watch)(nil), state.Fns{Save: (*Watch).save, Load: (*Watch).load}) - state.Register("pkg/sentry/vfs.Event", (*Event)(nil), state.Fns{Save: (*Event).save, Load: (*Event).load}) - state.Register("pkg/sentry/vfs.Mount", (*Mount)(nil), state.Fns{Save: (*Mount).save, Load: (*Mount).load}) - state.Register("pkg/sentry/vfs.MountNamespace", (*MountNamespace)(nil), state.Fns{Save: (*MountNamespace).save, Load: (*MountNamespace).load}) - state.Register("pkg/sentry/vfs.VirtualFilesystem", (*VirtualFilesystem)(nil), state.Fns{Save: (*VirtualFilesystem).save, Load: (*VirtualFilesystem).load}) - state.Register("pkg/sentry/vfs.VirtualDentry", (*VirtualDentry)(nil), state.Fns{Save: (*VirtualDentry).save, Load: (*VirtualDentry).load}) + state.Register((*Dentry)(nil)) + state.Register((*registeredDevice)(nil)) + state.Register((*RegisterDeviceOptions)(nil)) + state.Register((*epollInterestList)(nil)) + state.Register((*epollInterestEntry)(nil)) + state.Register((*eventList)(nil)) + state.Register((*eventEntry)(nil)) + state.Register((*Filesystem)(nil)) + state.Register((*registeredFilesystemType)(nil)) + state.Register((*Inotify)(nil)) + state.Register((*Watches)(nil)) + state.Register((*Watch)(nil)) + state.Register((*Event)(nil)) + state.Register((*Mount)(nil)) + state.Register((*MountNamespace)(nil)) + state.Register((*VirtualFilesystem)(nil)) + state.Register((*VirtualDentry)(nil)) } diff --git a/pkg/sentry/vfs/vfs_unsafe_state_autogen.go b/pkg/sentry/vfs/vfs_unsafe_state_autogen.go index ca9946ce4..37c5926c4 100644 --- a/pkg/sentry/vfs/vfs_unsafe_state_autogen.go +++ b/pkg/sentry/vfs/vfs_unsafe_state_autogen.go @@ -9,19 +9,32 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *mountTable) StateTypeName() string { + return "pkg/sentry/vfs.mountTable" +} + +func (x *mountTable) StateFields() []string { + return []string{ + "seed", + "size", + } +} + func (x *mountTable) beforeSave() {} -func (x *mountTable) save(m state.Map) { + +func (x *mountTable) StateSave(m state.Sink) { x.beforeSave() - m.Save("seed", &x.seed) - m.Save("size", &x.size) + m.Save(0, &x.seed) + m.Save(1, &x.size) } func (x *mountTable) afterLoad() {} -func (x *mountTable) load(m state.Map) { - m.Load("seed", &x.seed) - m.Load("size", &x.size) + +func (x *mountTable) StateLoad(m state.Source) { + m.Load(0, &x.seed) + m.Load(1, &x.size) } func init() { - state.Register("pkg/sentry/vfs.mountTable", (*mountTable)(nil), state.Fns{Save: (*mountTable).save, Load: (*mountTable).load}) + state.Register((*mountTable)(nil)) } diff --git a/pkg/state/addr_set.go b/pkg/state/addr_set.go index f8eaf0cd1..3cc0161b5 100644 --- a/pkg/state/addr_set.go +++ b/pkg/state/addr_set.go @@ -1,10 +1,6 @@ package state import ( - __generics_imported0 "reflect" -) - -import ( "bytes" "fmt" ) @@ -236,7 +232,7 @@ func (s *addrSet) UpperBoundGap(max uintptr) addrGapIterator { // segment can be merged with adjacent segments, Add will do so. If the new // segment would overlap an existing segment, Add returns false. If Add // succeeds, all existing iterators are invalidated. -func (s *addrSet) Add(r addrRange, val __generics_imported0.Value) bool { +func (s *addrSet) Add(r addrRange, val *objectEncodeState) bool { if r.Length() <= 0 { panic(fmt.Sprintf("invalid segment range %v", r)) } @@ -255,7 +251,7 @@ func (s *addrSet) Add(r addrRange, val __generics_imported0.Value) bool { // If it would overlap an existing segment, AddWithoutMerging does nothing and // returns false. If AddWithoutMerging succeeds, all existing iterators are // invalidated. -func (s *addrSet) AddWithoutMerging(r addrRange, val __generics_imported0.Value) bool { +func (s *addrSet) AddWithoutMerging(r addrRange, val *objectEncodeState) bool { if r.Length() <= 0 { panic(fmt.Sprintf("invalid segment range %v", r)) } @@ -282,7 +278,7 @@ func (s *addrSet) AddWithoutMerging(r addrRange, val __generics_imported0.Value) // Merge, but may be more efficient. Note that there is no unchecked variant of // Insert since Insert must retrieve and inspect gap's predecessor and // successor segments regardless. -func (s *addrSet) Insert(gap addrGapIterator, r addrRange, val __generics_imported0.Value) addrIterator { +func (s *addrSet) Insert(gap addrGapIterator, r addrRange, val *objectEncodeState) addrIterator { if r.Length() <= 0 { panic(fmt.Sprintf("invalid segment range %v", r)) } @@ -333,7 +329,7 @@ func (s *addrSet) Insert(gap addrGapIterator, r addrRange, val __generics_import // // If the gap cannot accommodate the segment, or if r is invalid, // InsertWithoutMerging panics. -func (s *addrSet) InsertWithoutMerging(gap addrGapIterator, r addrRange, val __generics_imported0.Value) addrIterator { +func (s *addrSet) InsertWithoutMerging(gap addrGapIterator, r addrRange, val *objectEncodeState) addrIterator { if r.Length() <= 0 { panic(fmt.Sprintf("invalid segment range %v", r)) } @@ -348,7 +344,7 @@ func (s *addrSet) InsertWithoutMerging(gap addrGapIterator, r addrRange, val __g // (including gap, but not including the returned iterator) are invalidated. // // Preconditions: r.Start >= gap.Start(); r.End <= gap.End(). -func (s *addrSet) InsertWithoutMergingUnchecked(gap addrGapIterator, r addrRange, val __generics_imported0.Value) addrIterator { +func (s *addrSet) InsertWithoutMergingUnchecked(gap addrGapIterator, r addrRange, val *objectEncodeState) addrIterator { gap = gap.node.rebalanceBeforeInsert(gap) splitMaxGap := addrtrackGaps != 0 && (gap.node.nrSegments == 0 || gap.Range().Length() == gap.node.maxGap.Get()) copy(gap.node.keys[gap.index+1:], gap.node.keys[gap.index:gap.node.nrSegments]) @@ -621,7 +617,7 @@ type addrnode struct { // Nodes store keys and values in separate arrays to maximize locality in // the common case (scanning keys for lookup). keys [addrmaxDegree - 1]addrRange - values [addrmaxDegree - 1]__generics_imported0.Value + values [addrmaxDegree - 1]*objectEncodeState children [addrmaxDegree]*addrnode } @@ -1175,20 +1171,20 @@ func (seg addrIterator) SetEnd(end uintptr) { } // Value returns a copy of the iterated segment's value. -func (seg addrIterator) Value() __generics_imported0.Value { +func (seg addrIterator) Value() *objectEncodeState { return seg.node.values[seg.index] } // ValuePtr returns a pointer to the iterated segment's value. The pointer is // invalidated if the iterator is invalidated. This operation does not // invalidate any iterators. -func (seg addrIterator) ValuePtr() *__generics_imported0.Value { +func (seg addrIterator) ValuePtr() **objectEncodeState { return &seg.node.values[seg.index] } // SetValue mutates the iterated segment's value. This operation does not // invalidate any iterators. -func (seg addrIterator) SetValue(val __generics_imported0.Value) { +func (seg addrIterator) SetValue(val *objectEncodeState) { seg.node.values[seg.index] = val } @@ -1492,7 +1488,7 @@ func addrsegmentAfterPosition(n *addrnode, i int) addrIterator { return addrIterator{n, i} } -func addrzeroValueSlice(slice []__generics_imported0.Value) { +func addrzeroValueSlice(slice []*objectEncodeState) { for i := range slice { addrSetFunctions{}.ClearValue(&slice[i]) @@ -1555,7 +1551,7 @@ func (n *addrnode) writeDebugString(buf *bytes.Buffer, prefix string) { type addrSegmentDataSlices struct { Start []uintptr End []uintptr - Values []__generics_imported0.Value + Values []*objectEncodeState } // ExportSortedSlice returns a copy of all segments in the given set, in ascending @@ -1599,7 +1595,7 @@ func (s *addrSet) ImportSortedSlices(sds *addrSegmentDataSlices) error { // // This should be used only for testing, and has been added to this package for // templating convenience. -func (s *addrSet) segmentTestCheck(expectedSegments int, segFunc func(int, addrRange, __generics_imported0.Value) error) error { +func (s *addrSet) segmentTestCheck(expectedSegments int, segFunc func(int, addrRange, *objectEncodeState) error) error { havePrev := false prev := uintptr(0) nrSegments := 0 diff --git a/pkg/state/complete_list.go b/pkg/state/complete_list.go new file mode 100644 index 000000000..decbad77b --- /dev/null +++ b/pkg/state/complete_list.go @@ -0,0 +1,193 @@ +package state + +// ElementMapper provides an identity mapping by default. +// +// This can be replaced to provide a struct that maps elements to linker +// objects, if they are not the same. An ElementMapper is not typically +// required if: Linker is left as is, Element is left as is, or Linker and +// Element are the same type. +type completeElementMapper struct{} + +// linkerFor maps an Element to a Linker. +// +// This default implementation should be inlined. +// +//go:nosplit +func (completeElementMapper) linkerFor(elem *objectDecodeState) *objectDecodeState { return elem } + +// List is an intrusive list. Entries can be added to or removed from the list +// in O(1) time and with no additional memory allocations. +// +// The zero value for List is an empty list ready to use. +// +// To iterate over a list (where l is a List): +// for e := l.Front(); e != nil; e = e.Next() { +// // do something with e. +// } +// +// +stateify savable +type completeList struct { + head *objectDecodeState + tail *objectDecodeState +} + +// Reset resets list l to the empty state. +func (l *completeList) Reset() { + l.head = nil + l.tail = nil +} + +// Empty returns true iff the list is empty. +func (l *completeList) Empty() bool { + return l.head == nil +} + +// Front returns the first element of list l or nil. +func (l *completeList) Front() *objectDecodeState { + return l.head +} + +// Back returns the last element of list l or nil. +func (l *completeList) Back() *objectDecodeState { + return l.tail +} + +// Len returns the number of elements in the list. +// +// NOTE: This is an O(n) operation. +func (l *completeList) Len() (count int) { + for e := l.Front(); e != nil; e = (completeElementMapper{}.linkerFor(e)).Next() { + count++ + } + return count +} + +// PushFront inserts the element e at the front of list l. +func (l *completeList) PushFront(e *objectDecodeState) { + linker := completeElementMapper{}.linkerFor(e) + linker.SetNext(l.head) + linker.SetPrev(nil) + if l.head != nil { + completeElementMapper{}.linkerFor(l.head).SetPrev(e) + } else { + l.tail = e + } + + l.head = e +} + +// PushBack inserts the element e at the back of list l. +func (l *completeList) PushBack(e *objectDecodeState) { + linker := completeElementMapper{}.linkerFor(e) + linker.SetNext(nil) + linker.SetPrev(l.tail) + if l.tail != nil { + completeElementMapper{}.linkerFor(l.tail).SetNext(e) + } else { + l.head = e + } + + l.tail = e +} + +// PushBackList inserts list m at the end of list l, emptying m. +func (l *completeList) PushBackList(m *completeList) { + if l.head == nil { + l.head = m.head + l.tail = m.tail + } else if m.head != nil { + completeElementMapper{}.linkerFor(l.tail).SetNext(m.head) + completeElementMapper{}.linkerFor(m.head).SetPrev(l.tail) + + l.tail = m.tail + } + m.head = nil + m.tail = nil +} + +// InsertAfter inserts e after b. +func (l *completeList) InsertAfter(b, e *objectDecodeState) { + bLinker := completeElementMapper{}.linkerFor(b) + eLinker := completeElementMapper{}.linkerFor(e) + + a := bLinker.Next() + + eLinker.SetNext(a) + eLinker.SetPrev(b) + bLinker.SetNext(e) + + if a != nil { + completeElementMapper{}.linkerFor(a).SetPrev(e) + } else { + l.tail = e + } +} + +// InsertBefore inserts e before a. +func (l *completeList) InsertBefore(a, e *objectDecodeState) { + aLinker := completeElementMapper{}.linkerFor(a) + eLinker := completeElementMapper{}.linkerFor(e) + + b := aLinker.Prev() + eLinker.SetNext(a) + eLinker.SetPrev(b) + aLinker.SetPrev(e) + + if b != nil { + completeElementMapper{}.linkerFor(b).SetNext(e) + } else { + l.head = e + } +} + +// Remove removes e from l. +func (l *completeList) Remove(e *objectDecodeState) { + linker := completeElementMapper{}.linkerFor(e) + prev := linker.Prev() + next := linker.Next() + + if prev != nil { + completeElementMapper{}.linkerFor(prev).SetNext(next) + } else if l.head == e { + l.head = next + } + + if next != nil { + completeElementMapper{}.linkerFor(next).SetPrev(prev) + } else if l.tail == e { + l.tail = prev + } + + linker.SetNext(nil) + linker.SetPrev(nil) +} + +// Entry is a default implementation of Linker. Users can add anonymous fields +// of this type to their structs to make them automatically implement the +// methods needed by List. +// +// +stateify savable +type completeEntry struct { + next *objectDecodeState + prev *objectDecodeState +} + +// Next returns the entry that follows e in the list. +func (e *completeEntry) Next() *objectDecodeState { + return e.next +} + +// Prev returns the entry that precedes e in the list. +func (e *completeEntry) Prev() *objectDecodeState { + return e.prev +} + +// SetNext assigns 'entry' as the entry that follows e in the list. +func (e *completeEntry) SetNext(elem *objectDecodeState) { + e.next = elem +} + +// SetPrev assigns 'entry' as the entry that precedes e in the list. +func (e *completeEntry) SetPrev(elem *objectDecodeState) { + e.prev = elem +} diff --git a/pkg/state/decode.go b/pkg/state/decode.go index 590c241a3..c9971cdf6 100644 --- a/pkg/state/decode.go +++ b/pkg/state/decode.go @@ -17,28 +17,49 @@ package state import ( "bytes" "context" - "encoding/binary" - "errors" "fmt" - "io" + "math" "reflect" - "sort" - "github.com/golang/protobuf/proto" - pb "gvisor.dev/gvisor/pkg/state/object_go_proto" + "gvisor.dev/gvisor/pkg/state/wire" ) -// objectState represents an object that may be in the process of being +// internalCallback is a interface called on object completion. +// +// There are two implementations: objectDecodeState & userCallback. +type internalCallback interface { + // source returns the dependent object. May be nil. + source() *objectDecodeState + + // callbackRun executes the callback. + callbackRun() +} + +// userCallback is an implementation of internalCallback. +type userCallback func() + +// source implements internalCallback.source. +func (userCallback) source() *objectDecodeState { + return nil +} + +// callbackRun implements internalCallback.callbackRun. +func (uc userCallback) callbackRun() { + uc() +} + +// objectDecodeState represents an object that may be in the process of being // decoded. Specifically, it represents either a decoded object, or an an // interest in a future object that will be decoded. When that interest is // registered (via register), the storage for the object will be created, but // it will not be decoded until the object is encountered in the stream. -type objectState struct { +type objectDecodeState struct { // id is the id for this object. - // - // If this field is zero, then this is an anonymous (unregistered, - // non-reference primitive) object. This is immutable. - id uint64 + id objectID + + // typ is the id for this typeID. This may be zero if this is not a + // type-registered structure. + typ typeID // obj is the object. This may or may not be valid yet, depending on // whether complete returns true. However, regardless of whether the @@ -57,69 +78,52 @@ type objectState struct { // blockedBy is the number of dependencies this object has. blockedBy int - // blocking is a list of the objects blocked by this one. - blocking []*objectState + // callbacksInline is inline storage for callbacks. + callbacksInline [2]internalCallback // callbacks is a set of callbacks to execute on load. - callbacks []func() - - // path is the decoding path to the object. - path recoverable -} - -// complete indicates the object is complete. -func (os *objectState) complete() bool { - return os.blockedBy == 0 && len(os.callbacks) == 0 -} - -// checkComplete checks for completion. If the object is complete, pending -// callbacks will be executed and checkComplete will be called on downstream -// objects (those depending on this one). -func (os *objectState) checkComplete(stats *Stats) { - if os.blockedBy > 0 { - return - } - stats.Start(os.obj) + callbacks []internalCallback - // Fire all callbacks. - for _, fn := range os.callbacks { - fn() - } - os.callbacks = nil - - // Clear all blocked objects. - for _, other := range os.blocking { - other.blockedBy-- - other.checkComplete(stats) - } - os.blocking = nil - stats.Done() + completeEntry } -// waitFor queues a dependency on the given object. -func (os *objectState) waitFor(other *objectState, callback func()) { - os.blockedBy++ - other.blocking = append(other.blocking, os) - if callback != nil { - other.callbacks = append(other.callbacks, callback) +// addCallback adds a callback to the objectDecodeState. +func (ods *objectDecodeState) addCallback(ic internalCallback) { + if ods.callbacks == nil { + ods.callbacks = ods.callbacksInline[:0] } + ods.callbacks = append(ods.callbacks, ic) } // findCycleFor returns when the given object is found in the blocking set. -func (os *objectState) findCycleFor(target *objectState) []*objectState { - for _, other := range os.blocking { - if other == target { - return []*objectState{target} +func (ods *objectDecodeState) findCycleFor(target *objectDecodeState) []*objectDecodeState { + for _, ic := range ods.callbacks { + other := ic.source() + if other != nil && other == target { + return []*objectDecodeState{target} } else if childList := other.findCycleFor(target); childList != nil { return append(childList, other) } } - return nil + + // This should not occur. + Failf("no deadlock found?") + panic("unreachable") } // findCycle finds a dependency cycle. -func (os *objectState) findCycle() []*objectState { - return append(os.findCycleFor(os), os) +func (ods *objectDecodeState) findCycle() []*objectDecodeState { + return append(ods.findCycleFor(ods), ods) +} + +// source implements internalCallback.source. +func (ods *objectDecodeState) source() *objectDecodeState { + return ods +} + +// callbackRun implements internalCallback.callbackRun. +func (ods *objectDecodeState) callbackRun() { + ods.blockedBy-- } // decodeState is a graph of objects in the process of being decoded. @@ -137,30 +141,66 @@ type decodeState struct { // ctx is the decode context. ctx context.Context + // r is the input stream. + r wire.Reader + + // types is the type database. + types typeDecodeDatabase + // objectByID is the set of objects in progress. - objectsByID map[uint64]*objectState + objectsByID []*objectDecodeState // deferred are objects that have been read, by no interest has been // registered yet. These will be decoded once interest in registered. - deferred map[uint64]*pb.Object + deferred map[objectID]wire.Object - // outstanding is the number of outstanding objects. - outstanding uint32 + // pending is the set of objects that are not yet complete. + pending completeList - // r is the input stream. - r io.Reader - - // stats is the passed stats object. - stats *Stats - - // recoverable is the panic recover facility. - recoverable + // stats tracks time data. + stats Stats } // lookup looks up an object in decodeState or returns nil if no such object // has been previously registered. -func (ds *decodeState) lookup(id uint64) *objectState { - return ds.objectsByID[id] +func (ds *decodeState) lookup(id objectID) *objectDecodeState { + if len(ds.objectsByID) < int(id) { + return nil + } + return ds.objectsByID[id-1] +} + +// checkComplete checks for completion. +func (ds *decodeState) checkComplete(ods *objectDecodeState) bool { + // Still blocked? + if ods.blockedBy > 0 { + return false + } + + // Track stats if relevant. + if ods.callbacks != nil && ods.typ != 0 { + ds.stats.start(ods.typ) + defer ds.stats.done() + } + + // Fire all callbacks. + for _, ic := range ods.callbacks { + ic.callbackRun() + } + + // Mark completed. + cbs := ods.callbacks + ods.callbacks = nil + ds.pending.Remove(ods) + + // Recursively check others. + for _, ic := range cbs { + if other := ic.source(); other != nil && other.blockedBy == 0 { + ds.checkComplete(other) + } + } + + return true // All set. } // wait registers a dependency on an object. @@ -168,11 +208,8 @@ func (ds *decodeState) lookup(id uint64) *objectState { // As a special case, we always allow _useable_ references back to the first // decoding object because it may have fields that are already decoded. We also // allow trivial self reference, since they can be handled internally. -func (ds *decodeState) wait(waiter *objectState, id uint64, callback func()) { +func (ds *decodeState) wait(waiter *objectDecodeState, id objectID, callback func()) { switch id { - case 0: - // Nil pointer; nothing to wait for. - fallthrough case waiter.id: // Trivial self reference. fallthrough @@ -184,107 +221,188 @@ func (ds *decodeState) wait(waiter *objectState, id uint64, callback func()) { return } + // Mark as blocked. + waiter.blockedBy++ + // No nil can be returned here. - waiter.waitFor(ds.lookup(id), callback) + other := ds.lookup(id) + if callback != nil { + // Add the additional user callback. + other.addCallback(userCallback(callback)) + } + + // Mark waiter as unblocked. + other.addCallback(waiter) } // waitObject notes a blocking relationship. -func (ds *decodeState) waitObject(os *objectState, p *pb.Object, callback func()) { - if rv, ok := p.Value.(*pb.Object_RefValue); ok { +func (ds *decodeState) waitObject(ods *objectDecodeState, encoded wire.Object, callback func()) { + if rv, ok := encoded.(*wire.Ref); ok && rv.Root != 0 { // Refs can encode pointers and maps. - ds.wait(os, rv.RefValue, callback) - } else if sv, ok := p.Value.(*pb.Object_SliceValue); ok { + ds.wait(ods, objectID(rv.Root), callback) + } else if sv, ok := encoded.(*wire.Slice); ok && sv.Ref.Root != 0 { // See decodeObject; we need to wait for the array (if non-nil). - ds.wait(os, sv.SliceValue.RefValue, callback) - } else if iv, ok := p.Value.(*pb.Object_InterfaceValue); ok { + ds.wait(ods, objectID(sv.Ref.Root), callback) + } else if iv, ok := encoded.(*wire.Interface); ok { // It's an interface (wait recurisvely). - ds.waitObject(os, iv.InterfaceValue.Value, callback) + ds.waitObject(ods, iv.Value, callback) } else if callback != nil { // Nothing to wait for: execute the callback immediately. callback() } } +// walkChild returns a child object from obj, given an accessor path. This is +// the decode-side equivalent to traverse in encode.go. +// +// For the purposes of this function, a child object is either a field within a +// struct or an array element, with one such indirection per element in +// path. The returned value may be an unexported field, so it may not be +// directly assignable. See unsafePointerTo. +func walkChild(path []wire.Dot, obj reflect.Value) reflect.Value { + // See wire.Ref.Dots. The path here is specified in reverse order. + for i := len(path) - 1; i >= 0; i-- { + switch pc := path[i].(type) { + case *wire.FieldName: // Must be a pointer. + if obj.Kind() != reflect.Struct { + Failf("next component in child path is a field name, but the current object is not a struct. Path: %v, current obj: %#v", path, obj) + } + obj = obj.FieldByName(string(*pc)) + case wire.Index: // Embedded. + if obj.Kind() != reflect.Array { + Failf("next component in child path is an array index, but the current object is not an array. Path: %v, current obj: %#v", path, obj) + } + obj = obj.Index(int(pc)) + default: + panic("unreachable: switch should be exhaustive") + } + } + return obj +} + // register registers a decode with a type. // // This type is only used to instantiate a new object if it has not been -// registered previously. -func (ds *decodeState) register(id uint64, typ reflect.Type) *objectState { - os, ok := ds.objectsByID[id] - if ok { - return os +// registered previously. This depends on the type provided if none is +// available in the object itself. +func (ds *decodeState) register(r *wire.Ref, typ reflect.Type) reflect.Value { + // Grow the objectsByID slice. + id := objectID(r.Root) + if len(ds.objectsByID) < int(id) { + ds.objectsByID = append(ds.objectsByID, make([]*objectDecodeState, int(id)-len(ds.objectsByID))...) + } + + // Does this object already exist? + ods := ds.objectsByID[id-1] + if ods != nil { + return walkChild(r.Dots, ods.obj) + } + + // Create the object. + if len(r.Dots) != 0 { + typ = ds.findType(r.Type) } + v := reflect.New(typ) + ods = &objectDecodeState{ + id: id, + obj: v.Elem(), + } + ds.objectsByID[id-1] = ods + ds.pending.PushBack(ods) - // Record in the object index. - if typ.Kind() == reflect.Map { - os = &objectState{id: id, obj: reflect.MakeMap(typ), path: ds.recoverable.copy()} - } else { - os = &objectState{id: id, obj: reflect.New(typ).Elem(), path: ds.recoverable.copy()} + // Process any deferred objects & callbacks. + if encoded, ok := ds.deferred[id]; ok { + delete(ds.deferred, id) + ds.decodeObject(ods, ods.obj, encoded) } - ds.objectsByID[id] = os - if o, ok := ds.deferred[id]; ok { - // There is a deferred object. - delete(ds.deferred, id) // Free memory. - ds.decodeObject(os, os.obj, o, "", nil) - } else { - // There is no deferred object. - ds.outstanding++ + return walkChild(r.Dots, ods.obj) +} + +// objectDecoder is for decoding structs. +type objectDecoder struct { + // ds is decodeState. + ds *decodeState + + // ods is current object being decoded. + ods *objectDecodeState + + // reconciledTypeEntry is the reconciled type information. + rte *reconciledTypeEntry + + // encoded is the encoded object state. + encoded *wire.Struct +} + +// load is helper for the public methods on Source. +func (od *objectDecoder) load(slot int, objPtr reflect.Value, wait bool, fn func()) { + // Note that we have reconciled the type and may remap the fields here + // to match what's expected by the decoder. The "slot" parameter here + // is in terms of the local type, where the fields in the encoded + // object are in terms of the wire object's type, which might be in a + // different order (but will have the same fields). + v := *od.encoded.Field(od.rte.FieldOrder[slot]) + od.ds.decodeObject(od.ods, objPtr.Elem(), v) + if wait { + // Mark this individual object a blocker. + od.ds.waitObject(od.ods, v, fn) } +} - return os +// aterLoad implements Source.AfterLoad. +func (od *objectDecoder) afterLoad(fn func()) { + // Queue the local callback; this will execute when all of the above + // data dependencies have been cleared. + od.ods.addCallback(userCallback(fn)) } // decodeStruct decodes a struct value. -func (ds *decodeState) decodeStruct(os *objectState, obj reflect.Value, s *pb.Struct) { - // Set the fields. - m := Map{newInternalMap(nil, ds, os)} - defer internalMapPool.Put(m.internalMap) - for _, field := range s.Fields { - m.data = append(m.data, entry{ - name: field.Name, - object: field.Value, - }) - } - - // Sort the fields for efficient searching. - // - // Technically, these should already appear in sorted order in the - // state ordering, so this cost is effectively a single scan to ensure - // that the order is correct. - if len(m.data) > 1 { - sort.Slice(m.data, func(i, j int) bool { - return m.data[i].name < m.data[j].name - }) - } - - // Invoke the load; this will recursively decode other objects. - fns, ok := registeredTypes.lookupFns(obj.Addr().Type()) - if ok { - // Invoke the loader. - fns.invokeLoad(obj.Addr(), m) - } else if obj.NumField() == 0 { - // Allow anonymous empty structs. - return - } else { +func (ds *decodeState) decodeStruct(ods *objectDecodeState, obj reflect.Value, encoded *wire.Struct) { + if encoded.TypeID == 0 { + // Allow anonymous empty structs, but only if the encoded + // object also has no fields. + if encoded.Fields() == 0 && obj.NumField() == 0 { + return + } + // Propagate an error. - panic(fmt.Errorf("unregistered type %s", obj.Type())) + Failf("empty struct on wire %#v has field mismatch with type %q", encoded, obj.Type().Name()) + } + + // Lookup the object type. + rte := ds.types.Lookup(typeID(encoded.TypeID), obj.Type()) + ods.typ = typeID(encoded.TypeID) + + // Invoke the loader. + od := objectDecoder{ + ds: ds, + ods: ods, + rte: rte, + encoded: encoded, + } + ds.stats.start(ods.typ) + defer ds.stats.done() + if sl, ok := obj.Addr().Interface().(SaverLoader); ok { + // Note: may be a registered empty struct which does not + // implement the saver/loader interfaces. + sl.StateLoad(Source{internal: od}) } } // decodeMap decodes a map value. -func (ds *decodeState) decodeMap(os *objectState, obj reflect.Value, m *pb.Map) { +func (ds *decodeState) decodeMap(ods *objectDecodeState, obj reflect.Value, encoded *wire.Map) { if obj.IsNil() { + // See pointerTo. obj.Set(reflect.MakeMap(obj.Type())) } - for i := 0; i < len(m.Keys); i++ { + for i := 0; i < len(encoded.Keys); i++ { // Decode the objects. kv := reflect.New(obj.Type().Key()).Elem() vv := reflect.New(obj.Type().Elem()).Elem() - ds.decodeObject(os, kv, m.Keys[i], ".(key %d)", i) - ds.decodeObject(os, vv, m.Values[i], "[%#v]", kv.Interface()) - ds.waitObject(os, m.Keys[i], nil) - ds.waitObject(os, m.Values[i], nil) + ds.decodeObject(ods, kv, encoded.Keys[i]) + ds.decodeObject(ods, vv, encoded.Values[i]) + ds.waitObject(ods, encoded.Keys[i], nil) + ds.waitObject(ods, encoded.Values[i], nil) // Set in the map. obj.SetMapIndex(kv, vv) @@ -292,271 +410,294 @@ func (ds *decodeState) decodeMap(os *objectState, obj reflect.Value, m *pb.Map) } // decodeArray decodes an array value. -func (ds *decodeState) decodeArray(os *objectState, obj reflect.Value, a *pb.Array) { - if len(a.Contents) != obj.Len() { - panic(fmt.Errorf("mismatching array length expect=%d, actual=%d", obj.Len(), len(a.Contents))) +func (ds *decodeState) decodeArray(ods *objectDecodeState, obj reflect.Value, encoded *wire.Array) { + if len(encoded.Contents) != obj.Len() { + Failf("mismatching array length expect=%d, actual=%d", obj.Len(), len(encoded.Contents)) } // Decode the contents into the array. - for i := 0; i < len(a.Contents); i++ { - ds.decodeObject(os, obj.Index(i), a.Contents[i], "[%d]", i) - ds.waitObject(os, a.Contents[i], nil) + for i := 0; i < len(encoded.Contents); i++ { + ds.decodeObject(ods, obj.Index(i), encoded.Contents[i]) + ds.waitObject(ods, encoded.Contents[i], nil) } } -// decodeInterface decodes an interface value. -func (ds *decodeState) decodeInterface(os *objectState, obj reflect.Value, i *pb.Interface) { - // Is this a nil value? - if i.Type == "" { - return // Just leave obj alone. +// findType finds the type for the given wire.TypeSpecs. +func (ds *decodeState) findType(t wire.TypeSpec) reflect.Type { + switch x := t.(type) { + case wire.TypeID: + typ := ds.types.LookupType(typeID(x)) + rte := ds.types.Lookup(typeID(x), typ) + return rte.LocalType + case *wire.TypeSpecPointer: + return reflect.PtrTo(ds.findType(x.Type)) + case *wire.TypeSpecArray: + return reflect.ArrayOf(int(x.Count), ds.findType(x.Type)) + case *wire.TypeSpecSlice: + return reflect.SliceOf(ds.findType(x.Type)) + case *wire.TypeSpecMap: + return reflect.MapOf(ds.findType(x.Key), ds.findType(x.Value)) + default: + // Should not happen. + Failf("unknown type %#v", t) } + panic("unreachable") +} - // Get the dispatchable type. This may not be used if the given - // reference has already been resolved, but if not we need to know the - // type to create. - t, ok := registeredTypes.lookupType(i.Type) - if !ok { - panic(fmt.Errorf("no valid type for %q", i.Type)) +// decodeInterface decodes an interface value. +func (ds *decodeState) decodeInterface(ods *objectDecodeState, obj reflect.Value, encoded *wire.Interface) { + if _, ok := encoded.Type.(wire.TypeSpecNil); ok { + // Special case; the nil object. Just decode directly, which + // will read nil from the wire (if encoded correctly). + ds.decodeObject(ods, obj, encoded.Value) + return } - if obj.Kind() != reflect.Map { - // Set the obj to be the given typed value; this actually sets - // obj to be a non-zero value -- namely, it inserts type - // information. There's no need to do this for maps. - obj.Set(reflect.Zero(t)) + // We now need to resolve the actual type. + typ := ds.findType(encoded.Type) + + // We need to imbue type information here, then we can proceed to + // decode normally. In order to avoid issues with setting value-types, + // we create a new non-interface version of this object. We will then + // set the interface object to be equal to whatever we decode. + origObj := obj + obj = reflect.New(typ).Elem() + defer origObj.Set(obj) + + // With the object now having sufficient type information to actually + // have Set called on it, we can proceed to decode the value. + ds.decodeObject(ods, obj, encoded.Value) +} + +// isFloatEq determines if x and y represent the same value. +func isFloatEq(x float64, y float64) bool { + switch { + case math.IsNaN(x): + return math.IsNaN(y) + case math.IsInf(x, 1): + return math.IsInf(y, 1) + case math.IsInf(x, -1): + return math.IsInf(y, -1) + default: + return x == y } +} - // Decode the dereferenced element; there is no need to wait here, as - // the interface object shares the current object state. - ds.decodeObject(os, obj, i.Value, ".(%s)", i.Type) +// isComplexEq determines if x and y represent the same value. +func isComplexEq(x complex128, y complex128) bool { + return isFloatEq(real(x), real(y)) && isFloatEq(imag(x), imag(y)) } // decodeObject decodes a object value. -func (ds *decodeState) decodeObject(os *objectState, obj reflect.Value, object *pb.Object, format string, param interface{}) { - ds.push(false, format, param) - ds.stats.Add(obj) - ds.stats.Start(obj) - - switch x := object.GetValue().(type) { - case *pb.Object_BoolValue: - obj.SetBool(x.BoolValue) - case *pb.Object_StringValue: - obj.SetString(string(x.StringValue)) - case *pb.Object_Int64Value: - obj.SetInt(x.Int64Value) - if obj.Int() != x.Int64Value { - panic(fmt.Errorf("signed integer truncated in %v for %s", object, obj.Type())) +func (ds *decodeState) decodeObject(ods *objectDecodeState, obj reflect.Value, encoded wire.Object) { + switch x := encoded.(type) { + case wire.Nil: // Fast path: first. + // We leave obj alone here. That's because if obj represents an + // interface, it may have been imbued with type information in + // decodeInterface, and we don't want to destroy that. + case *wire.Ref: + // Nil pointers may be encoded in a "forceValue" context. For + // those we just leave it alone as the value will already be + // correct (nil). + if id := objectID(x.Root); id == 0 { + return } - case *pb.Object_Uint64Value: - obj.SetUint(x.Uint64Value) - if obj.Uint() != x.Uint64Value { - panic(fmt.Errorf("unsigned integer truncated in %v for %s", object, obj.Type())) - } - case *pb.Object_DoubleValue: - obj.SetFloat(x.DoubleValue) - if obj.Float() != x.DoubleValue { - panic(fmt.Errorf("float truncated in %v for %s", object, obj.Type())) - } - case *pb.Object_RefValue: - // Resolve the pointer itself, even though the object may not - // be decoded yet. You need to use wait() in order to ensure - // that is the case. See wait above, and Map.Barrier. - if id := x.RefValue; id != 0 { - // Decoding the interface should have imparted type - // information, so from this point it's safe to resolve - // and use this dynamic information for actually - // creating the object in register. - // - // (For non-interfaces this is a no-op). - dyntyp := reflect.TypeOf(obj.Interface()) - if dyntyp.Kind() == reflect.Map { - // Remove the map object count here to avoid - // double counting, as this object will be - // counted again when it gets processed later. - // We do not add a reference count as the - // reference is artificial. - ds.stats.Remove(obj) - obj.Set(ds.register(id, dyntyp).obj) - } else if dyntyp.Kind() == reflect.Ptr { - ds.push(true /* dereference */, "", nil) - obj.Set(ds.register(id, dyntyp.Elem()).obj.Addr()) - ds.pop() - } else { - obj.Set(ds.register(id, dyntyp.Elem()).obj.Addr()) + + // Note that if this is a map type, we go through a level of + // indirection to allow for map aliasing. + if obj.Kind() == reflect.Map { + v := ds.register(x, obj.Type()) + if v.IsNil() { + // Note that we don't want to clobber the map + // if has already been decoded by decodeMap. We + // just make it so that we have a consistent + // reference when that eventually does happen. + v.Set(reflect.MakeMap(v.Type())) } - } else { - // We leave obj alone here. That's because if obj - // represents an interface, it may have been embued - // with type information in decodeInterface, and we - // don't want to destroy that information. + obj.Set(v) + return } - case *pb.Object_SliceValue: - // It's okay to slice the array here, since the contents will - // still be provided later on. These semantics are a bit - // strange but they are handled in the Map.Barrier properly. - // - // The special semantics of zero ref apply here too. - if id := x.SliceValue.RefValue; id != 0 && x.SliceValue.Capacity > 0 { - v := reflect.ArrayOf(int(x.SliceValue.Capacity), obj.Type().Elem()) - obj.Set(ds.register(id, v).obj.Slice3(0, int(x.SliceValue.Length), int(x.SliceValue.Capacity))) + + // Normal assignment: authoritative only if no dots. + v := ds.register(x, obj.Type().Elem()) + if v.IsValid() { + obj.Set(unsafePointerTo(v)) } - case *pb.Object_ArrayValue: - ds.decodeArray(os, obj, x.ArrayValue) - case *pb.Object_StructValue: - ds.decodeStruct(os, obj, x.StructValue) - case *pb.Object_MapValue: - ds.decodeMap(os, obj, x.MapValue) - case *pb.Object_InterfaceValue: - ds.decodeInterface(os, obj, x.InterfaceValue) - case *pb.Object_ByteArrayValue: - copyArray(obj, reflect.ValueOf(x.ByteArrayValue)) - case *pb.Object_Uint16ArrayValue: - // 16-bit slices are serialized as 32-bit slices. - // See object.proto for details. - s := x.Uint16ArrayValue.Values - t := obj.Slice(0, obj.Len()).Interface().([]uint16) - if len(t) != len(s) { - panic(fmt.Errorf("mismatching array length expect=%d, actual=%d", len(t), len(s))) + case wire.Bool: + obj.SetBool(bool(x)) + case wire.Int: + obj.SetInt(int64(x)) + if obj.Int() != int64(x) { + Failf("signed integer truncated from %v to %v", int64(x), obj.Int()) } - for i := range s { - t[i] = uint16(s[i]) + case wire.Uint: + obj.SetUint(uint64(x)) + if obj.Uint() != uint64(x) { + Failf("unsigned integer truncated from %v to %v", uint64(x), obj.Uint()) } - case *pb.Object_Uint32ArrayValue: - copyArray(obj, reflect.ValueOf(x.Uint32ArrayValue.Values)) - case *pb.Object_Uint64ArrayValue: - copyArray(obj, reflect.ValueOf(x.Uint64ArrayValue.Values)) - case *pb.Object_UintptrArrayValue: - copyArray(obj, castSlice(reflect.ValueOf(x.UintptrArrayValue.Values), reflect.TypeOf(uintptr(0)))) - case *pb.Object_Int8ArrayValue: - copyArray(obj, castSlice(reflect.ValueOf(x.Int8ArrayValue.Values), reflect.TypeOf(int8(0)))) - case *pb.Object_Int16ArrayValue: - // 16-bit slices are serialized as 32-bit slices. - // See object.proto for details. - s := x.Int16ArrayValue.Values - t := obj.Slice(0, obj.Len()).Interface().([]int16) - if len(t) != len(s) { - panic(fmt.Errorf("mismatching array length expect=%d, actual=%d", len(t), len(s))) + case wire.Float32: + obj.SetFloat(float64(x)) + case wire.Float64: + obj.SetFloat(float64(x)) + if !isFloatEq(obj.Float(), float64(x)) { + Failf("floating point number truncated from %v to %v", float64(x), obj.Float()) } - for i := range s { - t[i] = int16(s[i]) + case *wire.Complex64: + obj.SetComplex(complex128(*x)) + case *wire.Complex128: + obj.SetComplex(complex128(*x)) + if !isComplexEq(obj.Complex(), complex128(*x)) { + Failf("complex number truncated from %v to %v", complex128(*x), obj.Complex()) } - case *pb.Object_Int32ArrayValue: - copyArray(obj, reflect.ValueOf(x.Int32ArrayValue.Values)) - case *pb.Object_Int64ArrayValue: - copyArray(obj, reflect.ValueOf(x.Int64ArrayValue.Values)) - case *pb.Object_BoolArrayValue: - copyArray(obj, reflect.ValueOf(x.BoolArrayValue.Values)) - case *pb.Object_Float64ArrayValue: - copyArray(obj, reflect.ValueOf(x.Float64ArrayValue.Values)) - case *pb.Object_Float32ArrayValue: - copyArray(obj, reflect.ValueOf(x.Float32ArrayValue.Values)) + case *wire.String: + obj.SetString(string(*x)) + case *wire.Slice: + // See *wire.Ref above; same applies. + if id := objectID(x.Ref.Root); id == 0 { + return + } + // Note that it's fine to slice the array here and assume that + // contents will still be filled in later on. + typ := reflect.ArrayOf(int(x.Capacity), obj.Type().Elem()) // The object type. + v := ds.register(&x.Ref, typ) + obj.Set(v.Slice3(0, int(x.Length), int(x.Capacity))) + case *wire.Array: + ds.decodeArray(ods, obj, x) + case *wire.Struct: + ds.decodeStruct(ods, obj, x) + case *wire.Map: + ds.decodeMap(ods, obj, x) + case *wire.Interface: + ds.decodeInterface(ods, obj, x) default: // Shoud not happen, not propagated as an error. - panic(fmt.Sprintf("unknown object %v for %s", object, obj.Type())) - } - - ds.stats.Done() - ds.pop() -} - -func copyArray(dest reflect.Value, src reflect.Value) { - if dest.Len() != src.Len() { - panic(fmt.Errorf("mismatching array length expect=%d, actual=%d", dest.Len(), src.Len())) + Failf("unknown object %#v for %q", encoded, obj.Type().Name()) } - reflect.Copy(dest, castSlice(src, dest.Type().Elem())) } -// Deserialize deserializes the object state. +// Load deserializes the object graph rooted at obj. // // This function may panic and should be run in safely(). -func (ds *decodeState) Deserialize(obj reflect.Value) { - ds.objectsByID[1] = &objectState{id: 1, obj: obj, path: ds.recoverable.copy()} - ds.outstanding = 1 // The root object. +func (ds *decodeState) Load(obj reflect.Value) { + ds.stats.init() + defer ds.stats.fini(func(id typeID) string { + return ds.types.LookupName(id) + }) + + // Create the root object. + ds.objectsByID = append(ds.objectsByID, &objectDecodeState{ + id: 1, + obj: obj, + }) + + // Read the number of objects. + lastID, object, err := ReadHeader(ds.r) + if err != nil { + Failf("header error: %w", err) + } + if !object { + Failf("object missing") + } + + // Decode all objects. + var ( + encoded wire.Object + ods *objectDecodeState + id = objectID(1) + tid = typeID(1) + ) + if err := safely(func() { + // Decode all objects in the stream. + // + // Note that the structure of this decoding loop should match + // the raw decoding loop in printer.go. + for id <= objectID(lastID) { + // Unmarshal the object. + encoded = wire.Load(ds.r) + + // Is this a type object? Handle inline. + if wt, ok := encoded.(*wire.Type); ok { + ds.types.Register(wt) + tid++ + encoded = nil + continue + } - // Decode all objects in the stream. - // - // See above, we never process objects while we have no outstanding - // interests (other than the very first object). - for id := uint64(1); ds.outstanding > 0; id++ { - os := ds.lookup(id) - ds.stats.Start(os.obj) - - o, err := ds.readObject() - if err != nil { - panic(err) - } + // Actually resolve the object. + ods = ds.lookup(id) + if ods != nil { + // Decode the object. + ds.decodeObject(ods, ods.obj, encoded) + } else { + // If an object hasn't had interest registered + // previously or isn't yet valid, we deferred + // decoding until interest is registered. + ds.deferred[id] = encoded + } - if os != nil { - // Decode the object. - ds.from = &os.path - ds.decodeObject(os, os.obj, o, "", nil) - ds.outstanding-- + // For error handling. + ods = nil + encoded = nil + id++ + } + }); err != nil { + // Include as much information as we can, taking into account + // the possible state transitions above. + if ods != nil { + Failf("error decoding object ID %d (%T) from %#v: %w", id, ods.obj.Interface(), encoded, err) + } else if encoded != nil { + Failf("lookup error decoding object ID %d from %#v: %w", id, encoded, err) } else { - // If an object hasn't had interest registered - // previously, we deferred decoding until interest is - // registered. - ds.deferred[id] = o + Failf("general decoding error: %w", err) } - - ds.stats.Done() - } - - // Check the zero-length header at the end. - length, object, err := ReadHeader(ds.r) - if err != nil { - panic(err) - } - if length != 0 { - panic(fmt.Sprintf("expected zero-length terminal, got %d", length)) - } - if object { - panic("expected non-object terminal") } // Check if we have any deferred objects. - if count := len(ds.deferred); count > 0 { - // Shoud not happen, not propagated as an error. - panic(fmt.Sprintf("still have %d deferred objects", count)) - } - - // Scan and fire all callbacks. - for _, os := range ds.objectsByID { - os.checkComplete(ds.stats) + for id, encoded := range ds.deferred { + // Shoud never happen, the graph was bogus. + Failf("still have deferred objects: one is ID %d, %#v", id, encoded) } - // Check if we have any remaining dependency cycles. - for _, os := range ds.objectsByID { - if !os.complete() { - // This must be the result of a dependency cycle. - cycle := os.findCycle() - var buf bytes.Buffer - buf.WriteString("dependency cycle: {") - for i, cycleOS := range cycle { - if i > 0 { - buf.WriteString(" => ") + // Scan and fire all callbacks. We iterate over the list of incomplete + // objects until all have been finished. We stop iterating if no + // objects become complete (there is a dependency cycle). + // + // Note that we iterate backwards here, because there will be a strong + // tendendcy for blocking relationships to go from earlier objects to + // later (deeper) objects in the graph. This will reduce the number of + // iterations required to finish all objects. + if err := safely(func() { + for ds.pending.Back() != nil { + thisCycle := false + for ods = ds.pending.Back(); ods != nil; { + if ds.checkComplete(ods) { + thisCycle = true + break } - buf.WriteString(fmt.Sprintf("%s", cycleOS.obj.Type())) + ods = ods.Prev() + } + if !thisCycle { + break } - buf.WriteString("}") - // Panic as an error; propagate to the caller. - panic(errors.New(string(buf.Bytes()))) } - } -} - -type byteReader struct { - io.Reader -} - -// ReadByte implements io.ByteReader. -func (br byteReader) ReadByte() (byte, error) { - var b [1]byte - n, err := br.Reader.Read(b[:]) - if n > 0 { - return b[0], nil - } else if err != nil { - return 0, err - } else { - return 0, io.ErrUnexpectedEOF + }); err != nil { + Failf("error executing callbacks for %#v: %w", ods.obj.Interface(), err) + } + + // Check if we have any remaining dependency cycles. If there are any + // objects left in the pending list, then it must be due to a cycle. + if ods := ds.pending.Front(); ods != nil { + // This must be the result of a dependency cycle. + cycle := ods.findCycle() + var buf bytes.Buffer + buf.WriteString("dependency cycle: {") + for i, cycleOS := range cycle { + if i > 0 { + buf.WriteString(" => ") + } + fmt.Fprintf(&buf, "%q", cycleOS.obj.Type()) + } + buf.WriteString("}") + Failf("incomplete graph: %s", string(buf.Bytes())) } } @@ -565,45 +706,20 @@ func (br byteReader) ReadByte() (byte, error) { // Each object written to the statefile is prefixed with a header. See // WriteHeader for more information; these functions are exported to allow // non-state writes to the file to play nice with debugging tools. -func ReadHeader(r io.Reader) (length uint64, object bool, err error) { +func ReadHeader(r wire.Reader) (length uint64, object bool, err error) { // Read the header. - length, err = binary.ReadUvarint(byteReader{r}) + err = safely(func() { + length = wire.LoadUint(r) + }) if err != nil { - return + // On the header, pass raw I/O errors. + if sErr, ok := err.(*ErrState); ok { + return 0, false, sErr.Unwrap() + } } // Decode whether the object is valid. - object = length&0x1 != 0 - length = length >> 1 + object = length&objectFlag != 0 + length &^= objectFlag return } - -// readObject reads an object from the stream. -func (ds *decodeState) readObject() (*pb.Object, error) { - // Read the header. - length, object, err := ReadHeader(ds.r) - if err != nil { - return nil, err - } - if !object { - return nil, fmt.Errorf("invalid object header") - } - - // Read the object. - buf := make([]byte, length) - for done := 0; done < len(buf); { - n, err := ds.r.Read(buf[done:]) - done += n - if n == 0 && err != nil { - return nil, err - } - } - - // Unmarshal. - obj := new(pb.Object) - if err := proto.Unmarshal(buf, obj); err != nil { - return nil, err - } - - return obj, nil -} diff --git a/pkg/state/decode_unsafe.go b/pkg/state/decode_unsafe.go new file mode 100644 index 000000000..d048f61a1 --- /dev/null +++ b/pkg/state/decode_unsafe.go @@ -0,0 +1,27 @@ +// Copyright 2020 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 state + +import ( + "reflect" + "unsafe" +) + +// unsafePointerTo is logically equivalent to reflect.Value.Addr, but works on +// values representing unexported fields. This bypasses visibility, but not +// type safety. +func unsafePointerTo(obj reflect.Value) reflect.Value { + return reflect.NewAt(obj.Type(), unsafe.Pointer(obj.UnsafeAddr())) +} diff --git a/pkg/state/deferred_list.go b/pkg/state/deferred_list.go new file mode 100644 index 000000000..5aed02c95 --- /dev/null +++ b/pkg/state/deferred_list.go @@ -0,0 +1,178 @@ +package state + +// List is an intrusive list. Entries can be added to or removed from the list +// in O(1) time and with no additional memory allocations. +// +// The zero value for List is an empty list ready to use. +// +// To iterate over a list (where l is a List): +// for e := l.Front(); e != nil; e = e.Next() { +// // do something with e. +// } +// +// +stateify savable +type deferredList struct { + head *objectEncodeState + tail *objectEncodeState +} + +// Reset resets list l to the empty state. +func (l *deferredList) Reset() { + l.head = nil + l.tail = nil +} + +// Empty returns true iff the list is empty. +func (l *deferredList) Empty() bool { + return l.head == nil +} + +// Front returns the first element of list l or nil. +func (l *deferredList) Front() *objectEncodeState { + return l.head +} + +// Back returns the last element of list l or nil. +func (l *deferredList) Back() *objectEncodeState { + return l.tail +} + +// Len returns the number of elements in the list. +// +// NOTE: This is an O(n) operation. +func (l *deferredList) Len() (count int) { + for e := l.Front(); e != nil; e = (deferredMapper{}.linkerFor(e)).Next() { + count++ + } + return count +} + +// PushFront inserts the element e at the front of list l. +func (l *deferredList) PushFront(e *objectEncodeState) { + linker := deferredMapper{}.linkerFor(e) + linker.SetNext(l.head) + linker.SetPrev(nil) + if l.head != nil { + deferredMapper{}.linkerFor(l.head).SetPrev(e) + } else { + l.tail = e + } + + l.head = e +} + +// PushBack inserts the element e at the back of list l. +func (l *deferredList) PushBack(e *objectEncodeState) { + linker := deferredMapper{}.linkerFor(e) + linker.SetNext(nil) + linker.SetPrev(l.tail) + if l.tail != nil { + deferredMapper{}.linkerFor(l.tail).SetNext(e) + } else { + l.head = e + } + + l.tail = e +} + +// PushBackList inserts list m at the end of list l, emptying m. +func (l *deferredList) PushBackList(m *deferredList) { + if l.head == nil { + l.head = m.head + l.tail = m.tail + } else if m.head != nil { + deferredMapper{}.linkerFor(l.tail).SetNext(m.head) + deferredMapper{}.linkerFor(m.head).SetPrev(l.tail) + + l.tail = m.tail + } + m.head = nil + m.tail = nil +} + +// InsertAfter inserts e after b. +func (l *deferredList) InsertAfter(b, e *objectEncodeState) { + bLinker := deferredMapper{}.linkerFor(b) + eLinker := deferredMapper{}.linkerFor(e) + + a := bLinker.Next() + + eLinker.SetNext(a) + eLinker.SetPrev(b) + bLinker.SetNext(e) + + if a != nil { + deferredMapper{}.linkerFor(a).SetPrev(e) + } else { + l.tail = e + } +} + +// InsertBefore inserts e before a. +func (l *deferredList) InsertBefore(a, e *objectEncodeState) { + aLinker := deferredMapper{}.linkerFor(a) + eLinker := deferredMapper{}.linkerFor(e) + + b := aLinker.Prev() + eLinker.SetNext(a) + eLinker.SetPrev(b) + aLinker.SetPrev(e) + + if b != nil { + deferredMapper{}.linkerFor(b).SetNext(e) + } else { + l.head = e + } +} + +// Remove removes e from l. +func (l *deferredList) Remove(e *objectEncodeState) { + linker := deferredMapper{}.linkerFor(e) + prev := linker.Prev() + next := linker.Next() + + if prev != nil { + deferredMapper{}.linkerFor(prev).SetNext(next) + } else if l.head == e { + l.head = next + } + + if next != nil { + deferredMapper{}.linkerFor(next).SetPrev(prev) + } else if l.tail == e { + l.tail = prev + } + + linker.SetNext(nil) + linker.SetPrev(nil) +} + +// Entry is a default implementation of Linker. Users can add anonymous fields +// of this type to their structs to make them automatically implement the +// methods needed by List. +// +// +stateify savable +type deferredEntry struct { + next *objectEncodeState + prev *objectEncodeState +} + +// Next returns the entry that follows e in the list. +func (e *deferredEntry) Next() *objectEncodeState { + return e.next +} + +// Prev returns the entry that precedes e in the list. +func (e *deferredEntry) Prev() *objectEncodeState { + return e.prev +} + +// SetNext assigns 'entry' as the entry that follows e in the list. +func (e *deferredEntry) SetNext(elem *objectEncodeState) { + e.next = elem +} + +// SetPrev assigns 'entry' as the entry that precedes e in the list. +func (e *deferredEntry) SetPrev(elem *objectEncodeState) { + e.prev = elem +} diff --git a/pkg/state/encode.go b/pkg/state/encode.go index c5118d3a9..92fcad4e9 100644 --- a/pkg/state/encode.go +++ b/pkg/state/encode.go @@ -15,437 +15,797 @@ package state import ( - "container/list" "context" - "encoding/binary" - "fmt" - "io" "reflect" - "sort" - "github.com/golang/protobuf/proto" - pb "gvisor.dev/gvisor/pkg/state/object_go_proto" + "gvisor.dev/gvisor/pkg/state/wire" ) -// queuedObject is an object queued for encoding. -type queuedObject struct { - id uint64 - obj reflect.Value - path recoverable +// objectEncodeState the type and identity of an object occupying a memory +// address range. This is the value type for addrSet, and the intrusive entry +// for the pending and deferred lists. +type objectEncodeState struct { + // id is the assigned ID for this object. + id objectID + + // obj is the object value. Note that this may be replaced if we + // encounter an object that contains this object. When this happens (in + // resolve), we will update existing references approprately, below, + // and defer a re-encoding of the object. + obj reflect.Value + + // encoded is the encoded value of this object. Note that this may not + // be up to date if this object is still in the deferred list. + encoded wire.Object + + // how indicates whether this object should be encoded as a value. This + // is used only for deferred encoding. + how encodeStrategy + + // refs are the list of reference objects used by other objects + // referring to this object. When the object is updated, these + // references may be updated directly and automatically. + refs []*wire.Ref + + pendingEntry + deferredEntry } // encodeState is state used for encoding. // -// The encoding process is a breadth-first traversal of the object graph. The -// inherent races and dependencies are much simpler than the decode case. +// The encoding process constructs a representation of the in-memory graph of +// objects before a single object is serialized. This is done to ensure that +// all references can be fully disambiguated. See resolve for more details. type encodeState struct { // ctx is the encode context. ctx context.Context - // lastID is the last object ID. - // - // See idsByObject for context. Because of the special zero encoding - // used for reference values, the first ID must be 1. - lastID uint64 + // w is the output stream. + w wire.Writer - // idsByObject is a set of objects, indexed via: - // - // reflect.ValueOf(x).UnsafeAddr - // - // This provides IDs for objects. - idsByObject map[uintptr]uint64 + // types is the type database. + types typeEncodeDatabase + + // lastID is the last allocated object ID. + lastID objectID - // values stores values that span the addresses. + // values tracks the address ranges occupied by objects, along with the + // types of these objects. This is used to locate pointer targets, + // including pointers to fields within another type. // - // addrSet is a a generated type which efficiently stores ranges of - // addresses. When encoding pointers, these ranges are filled in and - // used to check for overlapping or conflicting pointers. This would - // indicate a pointer to an field, or a non-type safe value, neither of - // which are currently decodable. + // Multiple objects may overlap in memory iff the larger object fully + // contains the smaller one, and the type of the smaller object matches + // a field or array element's type at the appropriate offset. An + // arbitrary number of objects may be nested in this manner. // - // See the usage of values below for more context. + // Note that this does not track zero-sized objects, those are tracked + // by zeroValues below. values addrSet - // w is the output stream. - w io.Writer + // zeroValues tracks zero-sized objects. + zeroValues map[reflect.Type]*objectEncodeState - // pending is the list of objects to be serialized. - // - // This is a set of queuedObjects. - pending list.List + // deferred is the list of objects to be encoded. + deferred deferredList - // done is the a list of finished objects. - // - // This is kept to prevent garbage collection and address reuse. - done list.List + // pendingTypes is the list of types to be serialized. Serialization + // will occur when all objects have been encoded, but before pending is + // serialized. + pendingTypes []wire.Type - // stats is the passed stats object. - stats *Stats + // pending is the list of objects to be serialized. Serialization does + // not actually occur until the full object graph is computed. + pending pendingList - // recoverable is the panic recover facility. - recoverable + // stats tracks time data. + stats Stats } -// register looks up an ID, registering if necessary. +// isSameSizeParent returns true if child is a field value or element within +// parent. Only a struct or array can have a child value. +// +// isSameSizeParent deals with objects like this: +// +// struct child { +// // fields.. +// } // -// If the object was not previously registered, it is enqueued to be serialized. -// See the documentation for idsByObject for more information. -func (es *encodeState) register(obj reflect.Value) uint64 { - // It is not legal to call register for any non-pointer objects (see - // below), so we panic with a recoverable error if this is a mismatch. - if obj.Kind() != reflect.Ptr && obj.Kind() != reflect.Map { - panic(fmt.Errorf("non-pointer %#v registered", obj.Interface())) +// struct parent { +// c child +// } +// +// var p parent +// record(&p.c) +// +// Here, &p and &p.c occupy the exact same address range. +// +// Or like this: +// +// struct child { +// // fields +// } +// +// var arr [1]parent +// record(&arr[0]) +// +// Similarly, &arr[0] and &arr[0].c have the exact same address range. +// +// Precondition: parent and child must occupy the same memory. +func isSameSizeParent(parent reflect.Value, childType reflect.Type) bool { + switch parent.Kind() { + case reflect.Struct: + for i := 0; i < parent.NumField(); i++ { + field := parent.Field(i) + if field.Type() == childType { + return true + } + // Recurse through any intermediate types. + if isSameSizeParent(field, childType) { + return true + } + // Does it make sense to keep going if the first field + // doesn't match? Yes, because there might be an + // arbitrary number of zero-sized fields before we get + // a match, and childType itself can be zero-sized. + } + return false + case reflect.Array: + // The only case where an array with more than one elements can + // return true is if childType is zero-sized. In such cases, + // it's ambiguous which element contains the match since a + // zero-sized child object fully fits in any of the zero-sized + // elements in an array... However since all elements are of + // the same type, we only need to check one element. + // + // For non-zero-sized childTypes, parent.Len() must be 1, but a + // combination of the precondition and an implicit comparison + // between the array element size and childType ensures this. + return parent.Len() > 0 && isSameSizeParent(parent.Index(0), childType) + default: + return false } +} - addr := obj.Pointer() - if obj.Kind() == reflect.Ptr && obj.Elem().Type().Size() == 0 { - // For zero-sized objects, we always provide a unique ID. - // That's because the runtime internally multiplexes pointers - // to the same address. We can't be certain what the intent is - // with pointers to zero-sized objects, so we just give them - // all unique identities. - } else if id, ok := es.idsByObject[addr]; ok { - // Already registered. - return id - } - - // Ensure that the first ID given out is one. See note on lastID. The - // ID zero is used to indicate nil values. +// nextID returns the next valid ID. +func (es *encodeState) nextID() objectID { es.lastID++ - id := es.lastID - es.idsByObject[addr] = id - if obj.Kind() == reflect.Ptr { - // Dereference and treat as a pointer. - es.pending.PushBack(queuedObject{id: id, obj: obj.Elem(), path: es.recoverable.copy()}) - - // Register this object at all addresses. - typ := obj.Elem().Type() - if size := typ.Size(); size > 0 { - r := addrRange{addr, addr + size} - if !es.values.IsEmptyRange(r) { - old := es.values.LowerBoundSegment(addr).Value().Interface().(recoverable) - panic(fmt.Errorf("overlapping objects: [new object] %#v [existing object path] %s", obj.Interface(), old.path())) + return objectID(es.lastID) +} + +// dummyAddr points to the dummy zero-sized address. +var dummyAddr = reflect.ValueOf(new(struct{})).Pointer() + +// resolve records the address range occupied by an object. +func (es *encodeState) resolve(obj reflect.Value, ref *wire.Ref) { + addr := obj.Pointer() + + // Is this a map pointer? Just record the single address. It is not + // possible to take any pointers into the map internals. + if obj.Kind() == reflect.Map { + if addr == 0 { + // Just leave the nil reference alone. This is fine, we + // may need to encode as a reference in this way. We + // return nil for our objectEncodeState so that anyone + // depending on this value knows there's nothing there. + return + } + if seg, _ := es.values.Find(addr); seg.Ok() { + // Ensure the map types match. + existing := seg.Value() + if existing.obj.Type() != obj.Type() { + Failf("overlapping map objects at 0x%x: [new object] %#v [existing object type] %s", addr, obj, existing.obj) } - es.values.Add(r, reflect.ValueOf(es.recoverable.copy())) + + // No sense recording refs, maps may not be replaced by + // covering objects, they are maximal. + ref.Root = wire.Uint(existing.id) + return } + + // Record the map. + oes := &objectEncodeState{ + id: es.nextID(), + obj: obj, + how: encodeMapAsValue, + } + es.values.Add(addrRange{addr, addr + 1}, oes) + es.pending.PushBack(oes) + es.deferred.PushBack(oes) + + // See above: no ref recording. + ref.Root = wire.Uint(oes.id) + return + } + + // If not a map, then the object must be a pointer. + if obj.Kind() != reflect.Ptr { + Failf("attempt to record non-map and non-pointer object %#v", obj) + } + + obj = obj.Elem() // Value from here. + + // Is this a zero-sized type? + typ := obj.Type() + size := typ.Size() + if size == 0 { + if addr == dummyAddr { + // Zero-sized objects point to a dummy byte within the + // runtime. There's no sense recording this in the + // address map. We add this to the dedicated + // zeroValues. + // + // Note that zero-sized objects must be *true* + // zero-sized objects. They cannot be part of some + // larger object. In that case, they are assigned a + // 1-byte address at the end of the object. + oes, ok := es.zeroValues[typ] + if !ok { + oes = &objectEncodeState{ + id: es.nextID(), + obj: obj, + } + es.zeroValues[typ] = oes + es.pending.PushBack(oes) + es.deferred.PushBack(oes) + } + + // There's also no sense tracking back references. We + // know that this is a true zero-sized object, and not + // part of a larger container, so it will not change. + ref.Root = wire.Uint(oes.id) + return + } + size = 1 // See above. + } + + // Calculate the container. + end := addr + size + r := addrRange{addr, end} + if seg, _ := es.values.Find(addr); seg.Ok() { + existing := seg.Value() + switch { + case seg.Start() == addr && seg.End() == end && obj.Type() == existing.obj.Type(): + // The object is a perfect match. Happy path. Avoid the + // traversal and just return directly. We don't need to + // encode the type information or any dots here. + ref.Root = wire.Uint(existing.id) + existing.refs = append(existing.refs, ref) + return + + case (seg.Start() < addr && seg.End() >= end) || (seg.Start() <= addr && seg.End() > end): + // The previously registered object is larger than + // this, no need to update. But we expect some + // traversal below. + + case seg.Start() == addr && seg.End() == end: + if !isSameSizeParent(obj, existing.obj.Type()) { + break // Needs traversal. + } + fallthrough // Needs update. + + case (seg.Start() > addr && seg.End() <= end) || (seg.Start() >= addr && seg.End() < end): + // Update the object and redo the encoding. + old := existing.obj + existing.obj = obj + es.deferred.Remove(existing) + es.deferred.PushBack(existing) + + // The previously registered object is superseded by + // this new object. We are guaranteed to not have any + // mergeable neighbours in this segment set. + if !raceEnabled { + seg.SetRangeUnchecked(r) + } else { + // Add extra paranoid. This will be statically + // removed at compile time unless a race build. + es.values.Remove(seg) + es.values.Add(r, existing) + seg = es.values.LowerBoundSegment(addr) + } + + // Compute the traversal required & update references. + dots := traverse(obj.Type(), old.Type(), addr, seg.Start()) + wt := es.findType(obj.Type()) + for _, ref := range existing.refs { + ref.Dots = append(ref.Dots, dots...) + ref.Type = wt + } + default: + // There is a non-sensical overlap. + Failf("overlapping objects: [new object] %#v [existing object] %#v", obj, existing.obj) + } + + // Compute the new reference, record and return it. + ref.Root = wire.Uint(existing.id) + ref.Dots = traverse(existing.obj.Type(), obj.Type(), seg.Start(), addr) + ref.Type = es.findType(obj.Type()) + existing.refs = append(existing.refs, ref) + return + } + + // The only remaining case is a pointer value that doesn't overlap with + // any registered addresses. Create a new entry for it, and start + // tracking the first reference we just created. + oes := &objectEncodeState{ + id: es.nextID(), + obj: obj, + } + if !raceEnabled { + es.values.AddWithoutMerging(r, oes) } else { - // Push back the map itself; when maps are encoded from the - // top-level, forceMap will be equal to true. - es.pending.PushBack(queuedObject{id: id, obj: obj, path: es.recoverable.copy()}) + // Merges should never happen. This is just enabled extra + // sanity checks because the Merge function below will panic. + es.values.Add(r, oes) + } + es.pending.PushBack(oes) + es.deferred.PushBack(oes) + ref.Root = wire.Uint(oes.id) + oes.refs = append(oes.refs, ref) +} + +// traverse searches for a target object within a root object, where the target +// object is a struct field or array element within root, with potentially +// multiple intervening types. traverse returns the set of field or element +// traversals required to reach the target. +// +// Note that for efficiency, traverse returns the dots in the reverse order. +// That is, the first traversal required will be the last element of the list. +// +// Precondition: The target object must lie completely within the range defined +// by [rootAddr, rootAddr + sizeof(rootType)]. +func traverse(rootType, targetType reflect.Type, rootAddr, targetAddr uintptr) []wire.Dot { + // Recursion base case: the types actually match. + if targetType == rootType && targetAddr == rootAddr { + return nil } - return id + switch rootType.Kind() { + case reflect.Struct: + offset := targetAddr - rootAddr + for i := rootType.NumField(); i > 0; i-- { + field := rootType.Field(i - 1) + // The first field from the end with an offset that is + // smaller than or equal to our address offset is where + // the target is located. Traverse from there. + if field.Offset <= offset { + dots := traverse(field.Type, targetType, rootAddr+field.Offset, targetAddr) + fieldName := wire.FieldName(field.Name) + return append(dots, &fieldName) + } + } + // Should never happen; the target should be reachable. + Failf("no field in root type %v contains target type %v", rootType, targetType) + + case reflect.Array: + // Since arrays have homogenous types, all elements have the + // same size and we can compute where the target lives. This + // does not matter for the purpose of typing, but matters for + // the purpose of computing the address of the given index. + elemSize := int(rootType.Elem().Size()) + n := int(targetAddr-rootAddr) / elemSize // Relies on integer division rounding down. + if rootType.Len() < n { + Failf("traversal target of type %v @%x is beyond the end of the array type %v @%x with %v elements", + targetType, targetAddr, rootType, rootAddr, rootType.Len()) + } + dots := traverse(rootType.Elem(), targetType, rootAddr+uintptr(n*elemSize), targetAddr) + return append(dots, wire.Index(n)) + + default: + // For any other type, there's no possibility of aliasing so if + // the types didn't match earlier then we have an addresss + // collision which shouldn't be possible at this point. + Failf("traverse failed for root type %v and target type %v", rootType, targetType) + } + panic("unreachable") } // encodeMap encodes a map. -func (es *encodeState) encodeMap(obj reflect.Value) *pb.Map { - var ( - keys []*pb.Object - values []*pb.Object - ) +func (es *encodeState) encodeMap(obj reflect.Value, dest *wire.Object) { + if obj.IsNil() { + // Because there is a difference between a nil map and an empty + // map, we need to not decode in the case of a truly nil map. + *dest = wire.Nil{} + return + } + l := obj.Len() + m := &wire.Map{ + Keys: make([]wire.Object, l), + Values: make([]wire.Object, l), + } + *dest = m for i, k := range obj.MapKeys() { v := obj.MapIndex(k) - kp := es.encodeObject(k, false, ".(key %d)", i) - vp := es.encodeObject(v, false, "[%#v]", k.Interface()) - keys = append(keys, kp) - values = append(values, vp) + // Map keys must be encoded using the full value because the + // type will be omitted after the first key. + es.encodeObject(k, encodeAsValue, &m.Keys[i]) + es.encodeObject(v, encodeAsValue, &m.Values[i]) } - return &pb.Map{Keys: keys, Values: values} +} + +// objectEncoder is for encoding structs. +type objectEncoder struct { + // es is encodeState. + es *encodeState + + // encoded is the encoded struct. + encoded *wire.Struct +} + +// save is called by the public methods on Sink. +func (oe *objectEncoder) save(slot int, obj reflect.Value) { + fieldValue := oe.encoded.Field(slot) + oe.es.encodeObject(obj, encodeDefault, fieldValue) } // encodeStruct encodes a composite object. -func (es *encodeState) encodeStruct(obj reflect.Value) *pb.Struct { - // Invoke the save. - m := Map{newInternalMap(es, nil, nil)} - defer internalMapPool.Put(m.internalMap) +func (es *encodeState) encodeStruct(obj reflect.Value, dest *wire.Object) { + // Ensure that the obj is addressable. There are two cases when it is + // not. First, is when this is dispatched via SaveValue. Second, when + // this is a map key as a struct. Either way, we need to make a copy to + // obtain an addressable value. if !obj.CanAddr() { - // Force it to a * type of the above; this involves a copy. localObj := reflect.New(obj.Type()) localObj.Elem().Set(obj) obj = localObj.Elem() } - fns, ok := registeredTypes.lookupFns(obj.Addr().Type()) - if ok { - // Invoke the provided saver. - fns.invokeSave(obj.Addr(), m) - } else if obj.NumField() == 0 { - // Allow unregistered anonymous, empty structs. - return &pb.Struct{} - } else { - // Propagate an error. - panic(fmt.Errorf("unregistered type %T", obj.Interface())) - } - - // Sort the underlying slice, and check for duplicates. This is done - // once instead of on each add, because performing this sort once is - // far more efficient. - if len(m.data) > 1 { - sort.Slice(m.data, func(i, j int) bool { - return m.data[i].name < m.data[j].name - }) - for i := range m.data { - if i > 0 && m.data[i-1].name == m.data[i].name { - panic(fmt.Errorf("duplicate name %s", m.data[i].name)) - } + + // Prepare the value. + s := &wire.Struct{} + *dest = s + + // Look the type up in the database. + te, ok := es.types.Lookup(obj.Type()) + if te == nil { + if obj.NumField() == 0 { + // Allow unregistered anonymous, empty structs. This + // will just return success without ever invoking the + // passed function. This uses the immutable EmptyStruct + // variable to prevent an allocation in this case. + // + // Note that this mechanism does *not* work for + // interfaces in general. So you can't dispatch + // non-registered empty structs via interfaces because + // then they can't be restored. + s.Alloc(0) + return } + // We need a SaverLoader for struct types. + Failf("struct %T does not implement SaverLoader", obj.Interface()) } - - // Encode the resulting fields. - fields := make([]*pb.Field, 0, len(m.data)) - for _, e := range m.data { - fields = append(fields, &pb.Field{ - Name: e.name, - Value: e.object, - }) + if !ok { + // Queue the type to be serialized. + es.pendingTypes = append(es.pendingTypes, te.Type) } - // Return the encoded object. - return &pb.Struct{Fields: fields} + // Invoke the provided saver. + s.TypeID = wire.TypeID(te.ID) + s.Alloc(len(te.Fields)) + oe := objectEncoder{ + es: es, + encoded: s, + } + es.stats.start(te.ID) + defer es.stats.done() + if sl, ok := obj.Addr().Interface().(SaverLoader); ok { + // Note: may be a registered empty struct which does not + // implement the saver/loader interfaces. + sl.StateSave(Sink{internal: oe}) + } } // encodeArray encodes an array. -func (es *encodeState) encodeArray(obj reflect.Value) *pb.Array { - var ( - contents []*pb.Object - ) - for i := 0; i < obj.Len(); i++ { - entry := es.encodeObject(obj.Index(i), false, "[%d]", i) - contents = append(contents, entry) - } - return &pb.Array{Contents: contents} +func (es *encodeState) encodeArray(obj reflect.Value, dest *wire.Object) { + l := obj.Len() + a := &wire.Array{ + Contents: make([]wire.Object, l), + } + *dest = a + for i := 0; i < l; i++ { + // We need to encode the full value because arrays are encoded + // using the type information from only the first element. + es.encodeObject(obj.Index(i), encodeAsValue, &a.Contents[i]) + } +} + +// findType recursively finds type information. +func (es *encodeState) findType(typ reflect.Type) wire.TypeSpec { + // First: check if this is a proper type. It's possible for pointers, + // slices, arrays, maps, etc to all have some different type. + te, ok := es.types.Lookup(typ) + if te != nil { + if !ok { + // See encodeStruct. + es.pendingTypes = append(es.pendingTypes, te.Type) + } + return wire.TypeID(te.ID) + } + + switch typ.Kind() { + case reflect.Ptr: + return &wire.TypeSpecPointer{ + Type: es.findType(typ.Elem()), + } + case reflect.Slice: + return &wire.TypeSpecSlice{ + Type: es.findType(typ.Elem()), + } + case reflect.Array: + return &wire.TypeSpecArray{ + Count: wire.Uint(typ.Len()), + Type: es.findType(typ.Elem()), + } + case reflect.Map: + return &wire.TypeSpecMap{ + Key: es.findType(typ.Key()), + Value: es.findType(typ.Elem()), + } + default: + // After potentially chasing many pointers, the + // ultimate type of the object is not known. + Failf("type %q is not known", typ) + } + panic("unreachable") } // encodeInterface encodes an interface. -// -// Precondition: the value is not nil. -func (es *encodeState) encodeInterface(obj reflect.Value) *pb.Interface { - // Check for the nil interface. - obj = reflect.ValueOf(obj.Interface()) +func (es *encodeState) encodeInterface(obj reflect.Value, dest *wire.Object) { + // Dereference the object. + obj = obj.Elem() if !obj.IsValid() { - return &pb.Interface{ - Type: "", // left alone in decode. - Value: &pb.Object{Value: &pb.Object_RefValue{0}}, + // Special case: the nil object. + *dest = &wire.Interface{ + Type: wire.TypeSpecNil{}, + Value: wire.Nil{}, } + return } - // We have an interface value here. How do we save that? We - // resolve the underlying type and save it as a dispatchable. - typName, ok := registeredTypes.lookupName(obj.Type()) - if !ok { - panic(fmt.Errorf("type %s is not registered", obj.Type())) + + // Encode underlying object. + i := &wire.Interface{ + Type: es.findType(obj.Type()), } + *dest = i + es.encodeObject(obj, encodeAsValue, &i.Value) +} - // Encode the object again. - return &pb.Interface{ - Type: typName, - Value: es.encodeObject(obj, false, ".(%s)", typName), +// isPrimitive returns true if this is a primitive object, or a composite +// object composed entirely of primitives. +func isPrimitiveZero(typ reflect.Type) bool { + switch typ.Kind() { + case reflect.Ptr: + // Pointers are always treated as primitive types because we + // won't encode directly from here. Returning true here won't + // prevent the object from being encoded correctly. + return true + case reflect.Bool: + return true + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return true + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return true + case reflect.Float32, reflect.Float64: + return true + case reflect.Complex64, reflect.Complex128: + return true + case reflect.String: + return true + case reflect.Slice: + // The slice itself a primitive, but not necessarily the array + // that points to. This is similar to a pointer. + return true + case reflect.Array: + // We cannot treat an array as a primitive, because it may be + // composed of structures or other things with side-effects. + return isPrimitiveZero(typ.Elem()) + case reflect.Interface: + // Since we now that this type is the zero type, the interface + // value must be zero. Therefore this is primitive. + return true + case reflect.Struct: + return false + case reflect.Map: + // The isPrimitiveZero function is called only on zero-types to + // see if it's safe to serialize. Since a zero map has no + // elements, it is safe to treat as a primitive. + return true + default: + Failf("unknown type %q", typ.Name()) } + panic("unreachable") } -// encodeObject encodes an object. -// -// If mapAsValue is true, then a map will be encoded directly. -func (es *encodeState) encodeObject(obj reflect.Value, mapAsValue bool, format string, param interface{}) (object *pb.Object) { - es.push(false, format, param) - es.stats.Add(obj) - es.stats.Start(obj) +// encodeStrategy is the strategy used for encodeObject. +type encodeStrategy int +const ( + // encodeDefault means types are encoded normally as references. + encodeDefault encodeStrategy = iota + + // encodeAsValue means that types will never take short-circuited and + // will always be encoded as a normal value. + encodeAsValue + + // encodeMapAsValue means that even maps will be fully encoded. + encodeMapAsValue +) + +// encodeObject encodes an object. +func (es *encodeState) encodeObject(obj reflect.Value, how encodeStrategy, dest *wire.Object) { + if how == encodeDefault && isPrimitiveZero(obj.Type()) && obj.IsZero() { + *dest = wire.Nil{} + return + } switch obj.Kind() { + case reflect.Ptr: // Fast path: first. + r := new(wire.Ref) + *dest = r + if obj.IsNil() { + // May be in an array or elsewhere such that a value is + // required. So we encode as a reference to the zero + // object, which does not exist. Note that this has to + // be handled correctly in the decode path as well. + return + } + es.resolve(obj, r) case reflect.Bool: - object = &pb.Object{Value: &pb.Object_BoolValue{obj.Bool()}} + *dest = wire.Bool(obj.Bool()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - object = &pb.Object{Value: &pb.Object_Int64Value{obj.Int()}} + *dest = wire.Int(obj.Int()) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - object = &pb.Object{Value: &pb.Object_Uint64Value{obj.Uint()}} - case reflect.Float32, reflect.Float64: - object = &pb.Object{Value: &pb.Object_DoubleValue{obj.Float()}} + *dest = wire.Uint(obj.Uint()) + case reflect.Float32: + *dest = wire.Float32(obj.Float()) + case reflect.Float64: + *dest = wire.Float64(obj.Float()) + case reflect.Complex64: + c := wire.Complex64(obj.Complex()) + *dest = &c // Needs alloc. + case reflect.Complex128: + c := wire.Complex128(obj.Complex()) + *dest = &c // Needs alloc. + case reflect.String: + s := wire.String(obj.String()) + *dest = &s // Needs alloc. case reflect.Array: - switch obj.Type().Elem().Kind() { - case reflect.Uint8: - object = &pb.Object{Value: &pb.Object_ByteArrayValue{pbSlice(obj).Interface().([]byte)}} - case reflect.Uint16: - // 16-bit slices are serialized as 32-bit slices. - // See object.proto for details. - s := pbSlice(obj).Interface().([]uint16) - t := make([]uint32, len(s)) - for i := range s { - t[i] = uint32(s[i]) - } - object = &pb.Object{Value: &pb.Object_Uint16ArrayValue{&pb.Uint16S{Values: t}}} - case reflect.Uint32: - object = &pb.Object{Value: &pb.Object_Uint32ArrayValue{&pb.Uint32S{Values: pbSlice(obj).Interface().([]uint32)}}} - case reflect.Uint64: - object = &pb.Object{Value: &pb.Object_Uint64ArrayValue{&pb.Uint64S{Values: pbSlice(obj).Interface().([]uint64)}}} - case reflect.Uintptr: - object = &pb.Object{Value: &pb.Object_UintptrArrayValue{&pb.Uintptrs{Values: pbSlice(obj).Interface().([]uint64)}}} - case reflect.Int8: - object = &pb.Object{Value: &pb.Object_Int8ArrayValue{&pb.Int8S{Values: pbSlice(obj).Interface().([]byte)}}} - case reflect.Int16: - // 16-bit slices are serialized as 32-bit slices. - // See object.proto for details. - s := pbSlice(obj).Interface().([]int16) - t := make([]int32, len(s)) - for i := range s { - t[i] = int32(s[i]) - } - object = &pb.Object{Value: &pb.Object_Int16ArrayValue{&pb.Int16S{Values: t}}} - case reflect.Int32: - object = &pb.Object{Value: &pb.Object_Int32ArrayValue{&pb.Int32S{Values: pbSlice(obj).Interface().([]int32)}}} - case reflect.Int64: - object = &pb.Object{Value: &pb.Object_Int64ArrayValue{&pb.Int64S{Values: pbSlice(obj).Interface().([]int64)}}} - case reflect.Bool: - object = &pb.Object{Value: &pb.Object_BoolArrayValue{&pb.Bools{Values: pbSlice(obj).Interface().([]bool)}}} - case reflect.Float32: - object = &pb.Object{Value: &pb.Object_Float32ArrayValue{&pb.Float32S{Values: pbSlice(obj).Interface().([]float32)}}} - case reflect.Float64: - object = &pb.Object{Value: &pb.Object_Float64ArrayValue{&pb.Float64S{Values: pbSlice(obj).Interface().([]float64)}}} - default: - object = &pb.Object{Value: &pb.Object_ArrayValue{es.encodeArray(obj)}} - } + es.encodeArray(obj, dest) case reflect.Slice: - if obj.IsNil() || obj.Cap() == 0 { - // Handled specially in decode; store as nil value. - object = &pb.Object{Value: &pb.Object_RefValue{0}} - } else { - // Serialize a slice as the array plus length and capacity. - object = &pb.Object{Value: &pb.Object_SliceValue{&pb.Slice{ - Capacity: uint32(obj.Cap()), - Length: uint32(obj.Len()), - RefValue: es.register(arrayFromSlice(obj)), - }}} + s := &wire.Slice{ + Capacity: wire.Uint(obj.Cap()), + Length: wire.Uint(obj.Len()), } - case reflect.String: - object = &pb.Object{Value: &pb.Object_StringValue{[]byte(obj.String())}} - case reflect.Ptr: + *dest = s + // Note that we do need to provide a wire.Slice type here as + // how is not encodeDefault. If this were the case, then it + // would have been caught by the IsZero check above and we + // would have just used wire.Nil{}. if obj.IsNil() { - // Handled specially in decode; store as a nil value. - object = &pb.Object{Value: &pb.Object_RefValue{0}} - } else { - es.push(true /* dereference */, "", nil) - object = &pb.Object{Value: &pb.Object_RefValue{es.register(obj)}} - es.pop() + return } + // Slices need pointer resolution. + es.resolve(arrayFromSlice(obj), &s.Ref) case reflect.Interface: - // We don't check for IsNil here, as we want to encode type - // information. The case of the empty interface (no type, no - // value) is handled by encodeInteface. - object = &pb.Object{Value: &pb.Object_InterfaceValue{es.encodeInterface(obj)}} + es.encodeInterface(obj, dest) case reflect.Struct: - object = &pb.Object{Value: &pb.Object_StructValue{es.encodeStruct(obj)}} + es.encodeStruct(obj, dest) case reflect.Map: - if obj.IsNil() { - // Handled specially in decode; store as a nil value. - object = &pb.Object{Value: &pb.Object_RefValue{0}} - } else if mapAsValue { - // Encode the map directly. - object = &pb.Object{Value: &pb.Object_MapValue{es.encodeMap(obj)}} - } else { - // Encode a reference to the map. - // - // Remove the map object count here to avoid double - // counting, as this object will be counted again when - // it gets processed later. We do not add a reference - // count as the reference is artificial. - es.stats.Remove(obj) - object = &pb.Object{Value: &pb.Object_RefValue{es.register(obj)}} + if how == encodeMapAsValue { + es.encodeMap(obj, dest) + return } + r := new(wire.Ref) + *dest = r + es.resolve(obj, r) default: - panic(fmt.Errorf("unknown primitive %#v", obj.Interface())) + Failf("unknown object %#v", obj.Interface()) + panic("unreachable") } - - es.stats.Done() - es.pop() - return } -// Serialize serializes the object state. -// -// This function may panic and should be run in safely(). -func (es *encodeState) Serialize(obj reflect.Value) { - es.register(obj.Addr()) - - // Pop off the list until we're done. - for es.pending.Len() > 0 { - e := es.pending.Front() - - // Extract the queued object. - qo := e.Value.(queuedObject) - es.stats.Start(qo.obj) +// Save serializes the object graph rooted at obj. +func (es *encodeState) Save(obj reflect.Value) { + es.stats.init() + defer es.stats.fini(func(id typeID) string { + return es.pendingTypes[id-1].Name + }) + + // Resolve the first object, which should queue a pile of additional + // objects on the pending list. All queued objects should be fully + // resolved, and we should be able to serialize after this call. + var root wire.Ref + es.resolve(obj.Addr(), &root) + + // Encode the graph. + var oes *objectEncodeState + if err := safely(func() { + for oes = es.deferred.Front(); oes != nil; oes = es.deferred.Front() { + // Remove and encode the object. Note that as a result + // of this encoding, the object may be enqueued on the + // deferred list yet again. That's expected, and why it + // is removed first. + es.deferred.Remove(oes) + es.encodeObject(oes.obj, oes.how, &oes.encoded) + } + }); err != nil { + // Include the object in the error message. + Failf("encoding error at object %#v: %w", oes.obj.Interface(), err) + } - es.pending.Remove(e) + // Check that items are pending. + if es.pending.Front() == nil { + Failf("pending is empty?") + } - es.from = &qo.path - o := es.encodeObject(qo.obj, true, "", nil) + // Write the header with the number of objects. Note that there is no + // way that es.lastID could conflict with objectID, which would + // indicate that an impossibly large encoding. + if err := WriteHeader(es.w, uint64(es.lastID), true); err != nil { + Failf("error writing header: %w", err) + } - // Emit to our output stream. - if err := es.writeObject(qo.id, o); err != nil { - panic(err) + // Serialize all pending types and pending objects. Note that we don't + // bother removing from this list as we walk it because that just + // wastes time. It will not change after this point. + var id objectID + if err := safely(func() { + for _, wt := range es.pendingTypes { + // Encode the type. + wire.Save(es.w, &wt) } + for oes = es.pending.Front(); oes != nil; oes = oes.pendingEntry.Next() { + id++ // First object is 1. + if oes.id != id { + Failf("expected id %d, got %d", id, oes.id) + } - // Mark as done. - es.done.PushBack(e) - es.stats.Done() + // Marshall the object. + wire.Save(es.w, oes.encoded) + } + }); err != nil { + // Include the object and the error. + Failf("error serializing object %#v: %w", oes.encoded, err) } - // Write a zero-length terminal at the end; this is a sanity check - // applied at decode time as well (see decode.go). - if err := WriteHeader(es.w, 0, false); err != nil { - panic(err) + // Check what we wrote. + if id != es.lastID { + Failf("expected %d objects, wrote %d", es.lastID, id) } } +// objectFlag indicates that the length is a # of objects, rather than a raw +// byte length. When this is set on a length header in the stream, it may be +// decoded appropriately. +const objectFlag uint64 = 1 << 63 + // WriteHeader writes a header. // // Each object written to the statefile should be prefixed with a header. In // order to generate statefiles that play nicely with debugging tools, raw // writes should be prefixed with a header with object set to false and the // appropriate length. This will allow tools to skip these regions. -func WriteHeader(w io.Writer, length uint64, object bool) error { - // The lowest-order bit encodes whether this is a valid object. This is - // a purely internal convention, but allows the object flag to be - // returned from ReadHeader. - length = length << 1 +func WriteHeader(w wire.Writer, length uint64, object bool) error { + // Sanity check the length. + if length&objectFlag != 0 { + Failf("impossibly huge length: %d", length) + } if object { - length |= 0x1 + length |= objectFlag } // Write a header. - var hdr [32]byte - encodedLen := binary.PutUvarint(hdr[:], length) - for done := 0; done < encodedLen; { - n, err := w.Write(hdr[done:encodedLen]) - done += n - if n == 0 && err != nil { - return err - } - } - - return nil + return safely(func() { + wire.SaveUint(w, length) + }) } -// writeObject writes an object to the stream. -func (es *encodeState) writeObject(id uint64, obj *pb.Object) error { - // Marshal the proto. - buf, err := proto.Marshal(obj) - if err != nil { - return err - } +// pendingMapper is for the pending list. +type pendingMapper struct{} - // Write the object header. - if err := WriteHeader(es.w, uint64(len(buf)), true); err != nil { - return err - } +func (pendingMapper) linkerFor(oes *objectEncodeState) *pendingEntry { return &oes.pendingEntry } - // Write the object. - for done := 0; done < len(buf); { - n, err := es.w.Write(buf[done:]) - done += n - if n == 0 && err != nil { - return err - } - } +// deferredMapper is for the deferred list. +type deferredMapper struct{} - return nil -} +func (deferredMapper) linkerFor(oes *objectEncodeState) *deferredEntry { return &oes.deferredEntry } // addrSetFunctions is used by addrSet. type addrSetFunctions struct{} @@ -458,13 +818,24 @@ func (addrSetFunctions) MaxKey() uintptr { return ^uintptr(0) } -func (addrSetFunctions) ClearValue(val *reflect.Value) { +func (addrSetFunctions) ClearValue(val **objectEncodeState) { + *val = nil } -func (addrSetFunctions) Merge(_ addrRange, val1 reflect.Value, _ addrRange, val2 reflect.Value) (reflect.Value, bool) { - return val1, val1 == val2 +func (addrSetFunctions) Merge(r1 addrRange, val1 *objectEncodeState, r2 addrRange, val2 *objectEncodeState) (*objectEncodeState, bool) { + if val1.obj == val2.obj { + // This, should never happen. It would indicate that the same + // object exists in two non-contiguous address ranges. Note + // that this assertion can only be triggered if the race + // detector is enabled. + Failf("unexpected merge in addrSet @ %v and %v: %#v and %#v", r1, r2, val1.obj, val2.obj) + } + // Reject the merge. + return val1, false } -func (addrSetFunctions) Split(_ addrRange, val reflect.Value, _ uintptr) (reflect.Value, reflect.Value) { - return val, val +func (addrSetFunctions) Split(r addrRange, val *objectEncodeState, _ uintptr) (*objectEncodeState, *objectEncodeState) { + // A split should never happen: we don't remove ranges. + Failf("unexpected split in addrSet @ %v: %#v", r, val.obj) + panic("unreachable") } diff --git a/pkg/state/encode_unsafe.go b/pkg/state/encode_unsafe.go index 457e6dbb7..e0dad83b4 100644 --- a/pkg/state/encode_unsafe.go +++ b/pkg/state/encode_unsafe.go @@ -31,51 +31,3 @@ func arrayFromSlice(obj reflect.Value) reflect.Value { reflect.ArrayOf(obj.Cap(), obj.Type().Elem()), unsafe.Pointer(obj.Pointer())) } - -// pbSlice returns a protobuf-supported slice of the array and erase the -// original element type (which could be a defined type or non-supported type). -func pbSlice(obj reflect.Value) reflect.Value { - var typ reflect.Type - switch obj.Type().Elem().Kind() { - case reflect.Uint8: - typ = reflect.TypeOf(byte(0)) - case reflect.Uint16: - typ = reflect.TypeOf(uint16(0)) - case reflect.Uint32: - typ = reflect.TypeOf(uint32(0)) - case reflect.Uint64: - typ = reflect.TypeOf(uint64(0)) - case reflect.Uintptr: - typ = reflect.TypeOf(uint64(0)) - case reflect.Int8: - typ = reflect.TypeOf(byte(0)) - case reflect.Int16: - typ = reflect.TypeOf(int16(0)) - case reflect.Int32: - typ = reflect.TypeOf(int32(0)) - case reflect.Int64: - typ = reflect.TypeOf(int64(0)) - case reflect.Bool: - typ = reflect.TypeOf(bool(false)) - case reflect.Float32: - typ = reflect.TypeOf(float32(0)) - case reflect.Float64: - typ = reflect.TypeOf(float64(0)) - default: - panic("slice element is not of basic value type") - } - return reflect.NewAt( - reflect.ArrayOf(obj.Len(), typ), - unsafe.Pointer(obj.Slice(0, obj.Len()).Pointer()), - ).Elem().Slice(0, obj.Len()) -} - -func castSlice(obj reflect.Value, elemTyp reflect.Type) reflect.Value { - if obj.Type().Elem().Size() != elemTyp.Size() { - panic("cannot cast slice into other element type of different size") - } - return reflect.NewAt( - reflect.ArrayOf(obj.Len(), elemTyp), - unsafe.Pointer(obj.Slice(0, obj.Len()).Pointer()), - ).Elem() -} diff --git a/pkg/state/map.go b/pkg/state/map.go deleted file mode 100644 index 4f3ebb0da..000000000 --- a/pkg/state/map.go +++ /dev/null @@ -1,232 +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 state - -import ( - "context" - "fmt" - "reflect" - "sort" - "sync" - - pb "gvisor.dev/gvisor/pkg/state/object_go_proto" -) - -// entry is a single map entry. -type entry struct { - name string - object *pb.Object -} - -// internalMap is the internal Map state. -// -// These are recycled via a pool to avoid churn. -type internalMap struct { - // es is encodeState. - es *encodeState - - // ds is decodeState. - ds *decodeState - - // os is current object being decoded. - // - // This will always be nil during encode. - os *objectState - - // data stores the encoded values. - data []entry -} - -var internalMapPool = sync.Pool{ - New: func() interface{} { - return new(internalMap) - }, -} - -// newInternalMap returns a cached map. -func newInternalMap(es *encodeState, ds *decodeState, os *objectState) *internalMap { - m := internalMapPool.Get().(*internalMap) - m.es = es - m.ds = ds - m.os = os - if m.data != nil { - m.data = m.data[:0] - } - return m -} - -// Map is a generic state container. -// -// This is the object passed to Save and Load in order to store their state. -// -// Detailed documentation is available in individual methods. -type Map struct { - *internalMap -} - -// Save adds the given object to the map. -// -// You should pass always pointers to the object you are saving. For example: -// -// type X struct { -// A int -// B *int -// } -// -// func (x *X) Save(m Map) { -// m.Save("A", &x.A) -// m.Save("B", &x.B) -// } -// -// func (x *X) Load(m Map) { -// m.Load("A", &x.A) -// m.Load("B", &x.B) -// } -func (m Map) Save(name string, objPtr interface{}) { - m.save(name, reflect.ValueOf(objPtr).Elem(), ".%s") -} - -// SaveValue adds the given object value to the map. -// -// This should be used for values where pointers are not available, or casts -// are required during Save/Load. -// -// For example, if we want to cast external package type P.Foo to int64: -// -// type X struct { -// A P.Foo -// } -// -// func (x *X) Save(m Map) { -// m.SaveValue("A", int64(x.A)) -// } -// -// func (x *X) Load(m Map) { -// m.LoadValue("A", new(int64), func(x interface{}) { -// x.A = P.Foo(x.(int64)) -// }) -// } -func (m Map) SaveValue(name string, obj interface{}) { - m.save(name, reflect.ValueOf(obj), ".(value %s)") -} - -// save is helper for the above. It takes the name of value to save the field -// to, the field object (obj), and a format string that specifies how the -// field's saving logic is dispatched from the struct (normal, value, etc.). The -// format string should expect one string parameter, which is the name of the -// field. -func (m Map) save(name string, obj reflect.Value, format string) { - if m.es == nil { - // Not currently encoding. - m.Failf("no encode state for %q", name) - } - - // Attempt the encode. - // - // These are sorted at the end, after all objects are added and will be - // sorted and checked for duplicates (see encodeStruct). - m.data = append(m.data, entry{ - name: name, - object: m.es.encodeObject(obj, false, format, name), - }) -} - -// Load loads the given object from the map. -// -// See Save for an example. -func (m Map) Load(name string, objPtr interface{}) { - m.load(name, reflect.ValueOf(objPtr), false, nil, ".%s") -} - -// LoadWait loads the given objects from the map, and marks it as requiring all -// AfterLoad executions to complete prior to running this object's AfterLoad. -// -// See Save for an example. -func (m Map) LoadWait(name string, objPtr interface{}) { - m.load(name, reflect.ValueOf(objPtr), true, nil, ".(wait %s)") -} - -// LoadValue loads the given object value from the map. -// -// See SaveValue for an example. -func (m Map) LoadValue(name string, objPtr interface{}, fn func(interface{})) { - o := reflect.ValueOf(objPtr) - m.load(name, o, true, func() { fn(o.Elem().Interface()) }, ".(value %s)") -} - -// load is helper for the above. It takes the name of value to load the field -// from, the target field pointer (objPtr), whether load completion of the -// struct depends on the field's load completion (wait), the load completion -// logic (fn), and a format string that specifies how the field's loading logic -// is dispatched from the struct (normal, wait, value, etc.). The format string -// should expect one string parameter, which is the name of the field. -func (m Map) load(name string, objPtr reflect.Value, wait bool, fn func(), format string) { - if m.ds == nil { - // Not currently decoding. - m.Failf("no decode state for %q", name) - } - - // Find the object. - // - // These are sorted up front (and should appear in the state file - // sorted as well), so we can do a binary search here to ensure that - // large structs don't behave badly. - i := sort.Search(len(m.data), func(i int) bool { - return m.data[i].name >= name - }) - if i >= len(m.data) || m.data[i].name != name { - // There is no data for this name? - m.Failf("no data found for %q", name) - } - - // Perform the decode. - m.ds.decodeObject(m.os, objPtr.Elem(), m.data[i].object, format, name) - if wait { - // Mark this individual object a blocker. - m.ds.waitObject(m.os, m.data[i].object, fn) - } -} - -// Failf fails the save or restore with the provided message. Processing will -// stop after calling Failf, as the state package uses a panic & recover -// mechanism for state errors. You should defer any cleanup required. -func (m Map) Failf(format string, args ...interface{}) { - panic(fmt.Errorf(format, args...)) -} - -// AfterLoad schedules a function execution when all objects have been allocated -// and their automated loading and customized load logic have been executed. fn -// will not be executed until all of current object's dependencies' AfterLoad() -// logic, if exist, have been executed. -func (m Map) AfterLoad(fn func()) { - if m.ds == nil { - // Not currently decoding. - m.Failf("not decoding") - } - - // Queue the local callback; this will execute when all of the above - // data dependencies have been cleared. - m.os.callbacks = append(m.os.callbacks, fn) -} - -// Context returns the current context object. -func (m Map) Context() context.Context { - if m.es != nil { - return m.es.ctx - } else if m.ds != nil { - return m.ds.ctx - } - return context.Background() // No context. -} diff --git a/pkg/state/object_go_proto/object.pb.go b/pkg/state/object_go_proto/object.pb.go deleted file mode 100644 index dc5127149..000000000 --- a/pkg/state/object_go_proto/object.pb.go +++ /dev/null @@ -1,1195 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: pkg/state/object.proto - -package gvisor_state_statefile - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -type Slice struct { - Length uint32 `protobuf:"varint,1,opt,name=length,proto3" json:"length,omitempty"` - Capacity uint32 `protobuf:"varint,2,opt,name=capacity,proto3" json:"capacity,omitempty"` - RefValue uint64 `protobuf:"varint,3,opt,name=ref_value,json=refValue,proto3" json:"ref_value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Slice) Reset() { *m = Slice{} } -func (m *Slice) String() string { return proto.CompactTextString(m) } -func (*Slice) ProtoMessage() {} -func (*Slice) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{0} -} - -func (m *Slice) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Slice.Unmarshal(m, b) -} -func (m *Slice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Slice.Marshal(b, m, deterministic) -} -func (m *Slice) XXX_Merge(src proto.Message) { - xxx_messageInfo_Slice.Merge(m, src) -} -func (m *Slice) XXX_Size() int { - return xxx_messageInfo_Slice.Size(m) -} -func (m *Slice) XXX_DiscardUnknown() { - xxx_messageInfo_Slice.DiscardUnknown(m) -} - -var xxx_messageInfo_Slice proto.InternalMessageInfo - -func (m *Slice) GetLength() uint32 { - if m != nil { - return m.Length - } - return 0 -} - -func (m *Slice) GetCapacity() uint32 { - if m != nil { - return m.Capacity - } - return 0 -} - -func (m *Slice) GetRefValue() uint64 { - if m != nil { - return m.RefValue - } - return 0 -} - -type Array struct { - Contents []*Object `protobuf:"bytes,1,rep,name=contents,proto3" json:"contents,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Array) Reset() { *m = Array{} } -func (m *Array) String() string { return proto.CompactTextString(m) } -func (*Array) ProtoMessage() {} -func (*Array) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{1} -} - -func (m *Array) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Array.Unmarshal(m, b) -} -func (m *Array) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Array.Marshal(b, m, deterministic) -} -func (m *Array) XXX_Merge(src proto.Message) { - xxx_messageInfo_Array.Merge(m, src) -} -func (m *Array) XXX_Size() int { - return xxx_messageInfo_Array.Size(m) -} -func (m *Array) XXX_DiscardUnknown() { - xxx_messageInfo_Array.DiscardUnknown(m) -} - -var xxx_messageInfo_Array proto.InternalMessageInfo - -func (m *Array) GetContents() []*Object { - if m != nil { - return m.Contents - } - return nil -} - -type Map struct { - Keys []*Object `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"` - Values []*Object `protobuf:"bytes,2,rep,name=values,proto3" json:"values,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Map) Reset() { *m = Map{} } -func (m *Map) String() string { return proto.CompactTextString(m) } -func (*Map) ProtoMessage() {} -func (*Map) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{2} -} - -func (m *Map) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Map.Unmarshal(m, b) -} -func (m *Map) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Map.Marshal(b, m, deterministic) -} -func (m *Map) XXX_Merge(src proto.Message) { - xxx_messageInfo_Map.Merge(m, src) -} -func (m *Map) XXX_Size() int { - return xxx_messageInfo_Map.Size(m) -} -func (m *Map) XXX_DiscardUnknown() { - xxx_messageInfo_Map.DiscardUnknown(m) -} - -var xxx_messageInfo_Map proto.InternalMessageInfo - -func (m *Map) GetKeys() []*Object { - if m != nil { - return m.Keys - } - return nil -} - -func (m *Map) GetValues() []*Object { - if m != nil { - return m.Values - } - return nil -} - -type Interface struct { - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - Value *Object `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Interface) Reset() { *m = Interface{} } -func (m *Interface) String() string { return proto.CompactTextString(m) } -func (*Interface) ProtoMessage() {} -func (*Interface) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{3} -} - -func (m *Interface) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Interface.Unmarshal(m, b) -} -func (m *Interface) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Interface.Marshal(b, m, deterministic) -} -func (m *Interface) XXX_Merge(src proto.Message) { - xxx_messageInfo_Interface.Merge(m, src) -} -func (m *Interface) XXX_Size() int { - return xxx_messageInfo_Interface.Size(m) -} -func (m *Interface) XXX_DiscardUnknown() { - xxx_messageInfo_Interface.DiscardUnknown(m) -} - -var xxx_messageInfo_Interface proto.InternalMessageInfo - -func (m *Interface) GetType() string { - if m != nil { - return m.Type - } - return "" -} - -func (m *Interface) GetValue() *Object { - if m != nil { - return m.Value - } - return nil -} - -type Struct struct { - Fields []*Field `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Struct) Reset() { *m = Struct{} } -func (m *Struct) String() string { return proto.CompactTextString(m) } -func (*Struct) ProtoMessage() {} -func (*Struct) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{4} -} - -func (m *Struct) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Struct.Unmarshal(m, b) -} -func (m *Struct) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Struct.Marshal(b, m, deterministic) -} -func (m *Struct) XXX_Merge(src proto.Message) { - xxx_messageInfo_Struct.Merge(m, src) -} -func (m *Struct) XXX_Size() int { - return xxx_messageInfo_Struct.Size(m) -} -func (m *Struct) XXX_DiscardUnknown() { - xxx_messageInfo_Struct.DiscardUnknown(m) -} - -var xxx_messageInfo_Struct proto.InternalMessageInfo - -func (m *Struct) GetFields() []*Field { - if m != nil { - return m.Fields - } - return nil -} - -type Field struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Value *Object `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Field) Reset() { *m = Field{} } -func (m *Field) String() string { return proto.CompactTextString(m) } -func (*Field) ProtoMessage() {} -func (*Field) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{5} -} - -func (m *Field) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Field.Unmarshal(m, b) -} -func (m *Field) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Field.Marshal(b, m, deterministic) -} -func (m *Field) XXX_Merge(src proto.Message) { - xxx_messageInfo_Field.Merge(m, src) -} -func (m *Field) XXX_Size() int { - return xxx_messageInfo_Field.Size(m) -} -func (m *Field) XXX_DiscardUnknown() { - xxx_messageInfo_Field.DiscardUnknown(m) -} - -var xxx_messageInfo_Field proto.InternalMessageInfo - -func (m *Field) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *Field) GetValue() *Object { - if m != nil { - return m.Value - } - return nil -} - -type Uint16S struct { - Values []uint32 `protobuf:"varint,1,rep,packed,name=values,proto3" json:"values,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Uint16S) Reset() { *m = Uint16S{} } -func (m *Uint16S) String() string { return proto.CompactTextString(m) } -func (*Uint16S) ProtoMessage() {} -func (*Uint16S) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{6} -} - -func (m *Uint16S) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Uint16S.Unmarshal(m, b) -} -func (m *Uint16S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Uint16S.Marshal(b, m, deterministic) -} -func (m *Uint16S) XXX_Merge(src proto.Message) { - xxx_messageInfo_Uint16S.Merge(m, src) -} -func (m *Uint16S) XXX_Size() int { - return xxx_messageInfo_Uint16S.Size(m) -} -func (m *Uint16S) XXX_DiscardUnknown() { - xxx_messageInfo_Uint16S.DiscardUnknown(m) -} - -var xxx_messageInfo_Uint16S proto.InternalMessageInfo - -func (m *Uint16S) GetValues() []uint32 { - if m != nil { - return m.Values - } - return nil -} - -type Uint32S struct { - Values []uint32 `protobuf:"fixed32,1,rep,packed,name=values,proto3" json:"values,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Uint32S) Reset() { *m = Uint32S{} } -func (m *Uint32S) String() string { return proto.CompactTextString(m) } -func (*Uint32S) ProtoMessage() {} -func (*Uint32S) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{7} -} - -func (m *Uint32S) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Uint32S.Unmarshal(m, b) -} -func (m *Uint32S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Uint32S.Marshal(b, m, deterministic) -} -func (m *Uint32S) XXX_Merge(src proto.Message) { - xxx_messageInfo_Uint32S.Merge(m, src) -} -func (m *Uint32S) XXX_Size() int { - return xxx_messageInfo_Uint32S.Size(m) -} -func (m *Uint32S) XXX_DiscardUnknown() { - xxx_messageInfo_Uint32S.DiscardUnknown(m) -} - -var xxx_messageInfo_Uint32S proto.InternalMessageInfo - -func (m *Uint32S) GetValues() []uint32 { - if m != nil { - return m.Values - } - return nil -} - -type Uint64S struct { - Values []uint64 `protobuf:"fixed64,1,rep,packed,name=values,proto3" json:"values,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Uint64S) Reset() { *m = Uint64S{} } -func (m *Uint64S) String() string { return proto.CompactTextString(m) } -func (*Uint64S) ProtoMessage() {} -func (*Uint64S) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{8} -} - -func (m *Uint64S) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Uint64S.Unmarshal(m, b) -} -func (m *Uint64S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Uint64S.Marshal(b, m, deterministic) -} -func (m *Uint64S) XXX_Merge(src proto.Message) { - xxx_messageInfo_Uint64S.Merge(m, src) -} -func (m *Uint64S) XXX_Size() int { - return xxx_messageInfo_Uint64S.Size(m) -} -func (m *Uint64S) XXX_DiscardUnknown() { - xxx_messageInfo_Uint64S.DiscardUnknown(m) -} - -var xxx_messageInfo_Uint64S proto.InternalMessageInfo - -func (m *Uint64S) GetValues() []uint64 { - if m != nil { - return m.Values - } - return nil -} - -type Uintptrs struct { - Values []uint64 `protobuf:"fixed64,1,rep,packed,name=values,proto3" json:"values,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Uintptrs) Reset() { *m = Uintptrs{} } -func (m *Uintptrs) String() string { return proto.CompactTextString(m) } -func (*Uintptrs) ProtoMessage() {} -func (*Uintptrs) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{9} -} - -func (m *Uintptrs) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Uintptrs.Unmarshal(m, b) -} -func (m *Uintptrs) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Uintptrs.Marshal(b, m, deterministic) -} -func (m *Uintptrs) XXX_Merge(src proto.Message) { - xxx_messageInfo_Uintptrs.Merge(m, src) -} -func (m *Uintptrs) XXX_Size() int { - return xxx_messageInfo_Uintptrs.Size(m) -} -func (m *Uintptrs) XXX_DiscardUnknown() { - xxx_messageInfo_Uintptrs.DiscardUnknown(m) -} - -var xxx_messageInfo_Uintptrs proto.InternalMessageInfo - -func (m *Uintptrs) GetValues() []uint64 { - if m != nil { - return m.Values - } - return nil -} - -type Int8S struct { - Values []byte `protobuf:"bytes,1,opt,name=values,proto3" json:"values,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Int8S) Reset() { *m = Int8S{} } -func (m *Int8S) String() string { return proto.CompactTextString(m) } -func (*Int8S) ProtoMessage() {} -func (*Int8S) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{10} -} - -func (m *Int8S) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Int8S.Unmarshal(m, b) -} -func (m *Int8S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Int8S.Marshal(b, m, deterministic) -} -func (m *Int8S) XXX_Merge(src proto.Message) { - xxx_messageInfo_Int8S.Merge(m, src) -} -func (m *Int8S) XXX_Size() int { - return xxx_messageInfo_Int8S.Size(m) -} -func (m *Int8S) XXX_DiscardUnknown() { - xxx_messageInfo_Int8S.DiscardUnknown(m) -} - -var xxx_messageInfo_Int8S proto.InternalMessageInfo - -func (m *Int8S) GetValues() []byte { - if m != nil { - return m.Values - } - return nil -} - -type Int16S struct { - Values []int32 `protobuf:"varint,1,rep,packed,name=values,proto3" json:"values,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Int16S) Reset() { *m = Int16S{} } -func (m *Int16S) String() string { return proto.CompactTextString(m) } -func (*Int16S) ProtoMessage() {} -func (*Int16S) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{11} -} - -func (m *Int16S) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Int16S.Unmarshal(m, b) -} -func (m *Int16S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Int16S.Marshal(b, m, deterministic) -} -func (m *Int16S) XXX_Merge(src proto.Message) { - xxx_messageInfo_Int16S.Merge(m, src) -} -func (m *Int16S) XXX_Size() int { - return xxx_messageInfo_Int16S.Size(m) -} -func (m *Int16S) XXX_DiscardUnknown() { - xxx_messageInfo_Int16S.DiscardUnknown(m) -} - -var xxx_messageInfo_Int16S proto.InternalMessageInfo - -func (m *Int16S) GetValues() []int32 { - if m != nil { - return m.Values - } - return nil -} - -type Int32S struct { - Values []int32 `protobuf:"fixed32,1,rep,packed,name=values,proto3" json:"values,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Int32S) Reset() { *m = Int32S{} } -func (m *Int32S) String() string { return proto.CompactTextString(m) } -func (*Int32S) ProtoMessage() {} -func (*Int32S) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{12} -} - -func (m *Int32S) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Int32S.Unmarshal(m, b) -} -func (m *Int32S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Int32S.Marshal(b, m, deterministic) -} -func (m *Int32S) XXX_Merge(src proto.Message) { - xxx_messageInfo_Int32S.Merge(m, src) -} -func (m *Int32S) XXX_Size() int { - return xxx_messageInfo_Int32S.Size(m) -} -func (m *Int32S) XXX_DiscardUnknown() { - xxx_messageInfo_Int32S.DiscardUnknown(m) -} - -var xxx_messageInfo_Int32S proto.InternalMessageInfo - -func (m *Int32S) GetValues() []int32 { - if m != nil { - return m.Values - } - return nil -} - -type Int64S struct { - Values []int64 `protobuf:"fixed64,1,rep,packed,name=values,proto3" json:"values,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Int64S) Reset() { *m = Int64S{} } -func (m *Int64S) String() string { return proto.CompactTextString(m) } -func (*Int64S) ProtoMessage() {} -func (*Int64S) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{13} -} - -func (m *Int64S) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Int64S.Unmarshal(m, b) -} -func (m *Int64S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Int64S.Marshal(b, m, deterministic) -} -func (m *Int64S) XXX_Merge(src proto.Message) { - xxx_messageInfo_Int64S.Merge(m, src) -} -func (m *Int64S) XXX_Size() int { - return xxx_messageInfo_Int64S.Size(m) -} -func (m *Int64S) XXX_DiscardUnknown() { - xxx_messageInfo_Int64S.DiscardUnknown(m) -} - -var xxx_messageInfo_Int64S proto.InternalMessageInfo - -func (m *Int64S) GetValues() []int64 { - if m != nil { - return m.Values - } - return nil -} - -type Bools struct { - Values []bool `protobuf:"varint,1,rep,packed,name=values,proto3" json:"values,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Bools) Reset() { *m = Bools{} } -func (m *Bools) String() string { return proto.CompactTextString(m) } -func (*Bools) ProtoMessage() {} -func (*Bools) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{14} -} - -func (m *Bools) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Bools.Unmarshal(m, b) -} -func (m *Bools) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Bools.Marshal(b, m, deterministic) -} -func (m *Bools) XXX_Merge(src proto.Message) { - xxx_messageInfo_Bools.Merge(m, src) -} -func (m *Bools) XXX_Size() int { - return xxx_messageInfo_Bools.Size(m) -} -func (m *Bools) XXX_DiscardUnknown() { - xxx_messageInfo_Bools.DiscardUnknown(m) -} - -var xxx_messageInfo_Bools proto.InternalMessageInfo - -func (m *Bools) GetValues() []bool { - if m != nil { - return m.Values - } - return nil -} - -type Float64S struct { - Values []float64 `protobuf:"fixed64,1,rep,packed,name=values,proto3" json:"values,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Float64S) Reset() { *m = Float64S{} } -func (m *Float64S) String() string { return proto.CompactTextString(m) } -func (*Float64S) ProtoMessage() {} -func (*Float64S) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{15} -} - -func (m *Float64S) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Float64S.Unmarshal(m, b) -} -func (m *Float64S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Float64S.Marshal(b, m, deterministic) -} -func (m *Float64S) XXX_Merge(src proto.Message) { - xxx_messageInfo_Float64S.Merge(m, src) -} -func (m *Float64S) XXX_Size() int { - return xxx_messageInfo_Float64S.Size(m) -} -func (m *Float64S) XXX_DiscardUnknown() { - xxx_messageInfo_Float64S.DiscardUnknown(m) -} - -var xxx_messageInfo_Float64S proto.InternalMessageInfo - -func (m *Float64S) GetValues() []float64 { - if m != nil { - return m.Values - } - return nil -} - -type Float32S struct { - Values []float32 `protobuf:"fixed32,1,rep,packed,name=values,proto3" json:"values,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Float32S) Reset() { *m = Float32S{} } -func (m *Float32S) String() string { return proto.CompactTextString(m) } -func (*Float32S) ProtoMessage() {} -func (*Float32S) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{16} -} - -func (m *Float32S) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Float32S.Unmarshal(m, b) -} -func (m *Float32S) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Float32S.Marshal(b, m, deterministic) -} -func (m *Float32S) XXX_Merge(src proto.Message) { - xxx_messageInfo_Float32S.Merge(m, src) -} -func (m *Float32S) XXX_Size() int { - return xxx_messageInfo_Float32S.Size(m) -} -func (m *Float32S) XXX_DiscardUnknown() { - xxx_messageInfo_Float32S.DiscardUnknown(m) -} - -var xxx_messageInfo_Float32S proto.InternalMessageInfo - -func (m *Float32S) GetValues() []float32 { - if m != nil { - return m.Values - } - return nil -} - -type Object struct { - // Types that are valid to be assigned to Value: - // *Object_BoolValue - // *Object_StringValue - // *Object_Int64Value - // *Object_Uint64Value - // *Object_DoubleValue - // *Object_RefValue - // *Object_SliceValue - // *Object_ArrayValue - // *Object_InterfaceValue - // *Object_StructValue - // *Object_MapValue - // *Object_ByteArrayValue - // *Object_Uint16ArrayValue - // *Object_Uint32ArrayValue - // *Object_Uint64ArrayValue - // *Object_UintptrArrayValue - // *Object_Int8ArrayValue - // *Object_Int16ArrayValue - // *Object_Int32ArrayValue - // *Object_Int64ArrayValue - // *Object_BoolArrayValue - // *Object_Float64ArrayValue - // *Object_Float32ArrayValue - Value isObject_Value `protobuf_oneof:"value"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Object) Reset() { *m = Object{} } -func (m *Object) String() string { return proto.CompactTextString(m) } -func (*Object) ProtoMessage() {} -func (*Object) Descriptor() ([]byte, []int) { - return fileDescriptor_3dee2c1912d4d62d, []int{17} -} - -func (m *Object) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Object.Unmarshal(m, b) -} -func (m *Object) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Object.Marshal(b, m, deterministic) -} -func (m *Object) XXX_Merge(src proto.Message) { - xxx_messageInfo_Object.Merge(m, src) -} -func (m *Object) XXX_Size() int { - return xxx_messageInfo_Object.Size(m) -} -func (m *Object) XXX_DiscardUnknown() { - xxx_messageInfo_Object.DiscardUnknown(m) -} - -var xxx_messageInfo_Object proto.InternalMessageInfo - -type isObject_Value interface { - isObject_Value() -} - -type Object_BoolValue struct { - BoolValue bool `protobuf:"varint,1,opt,name=bool_value,json=boolValue,proto3,oneof"` -} - -type Object_StringValue struct { - StringValue []byte `protobuf:"bytes,2,opt,name=string_value,json=stringValue,proto3,oneof"` -} - -type Object_Int64Value struct { - Int64Value int64 `protobuf:"varint,3,opt,name=int64_value,json=int64Value,proto3,oneof"` -} - -type Object_Uint64Value struct { - Uint64Value uint64 `protobuf:"varint,4,opt,name=uint64_value,json=uint64Value,proto3,oneof"` -} - -type Object_DoubleValue struct { - DoubleValue float64 `protobuf:"fixed64,5,opt,name=double_value,json=doubleValue,proto3,oneof"` -} - -type Object_RefValue struct { - RefValue uint64 `protobuf:"varint,6,opt,name=ref_value,json=refValue,proto3,oneof"` -} - -type Object_SliceValue struct { - SliceValue *Slice `protobuf:"bytes,7,opt,name=slice_value,json=sliceValue,proto3,oneof"` -} - -type Object_ArrayValue struct { - ArrayValue *Array `protobuf:"bytes,8,opt,name=array_value,json=arrayValue,proto3,oneof"` -} - -type Object_InterfaceValue struct { - InterfaceValue *Interface `protobuf:"bytes,9,opt,name=interface_value,json=interfaceValue,proto3,oneof"` -} - -type Object_StructValue struct { - StructValue *Struct `protobuf:"bytes,10,opt,name=struct_value,json=structValue,proto3,oneof"` -} - -type Object_MapValue struct { - MapValue *Map `protobuf:"bytes,11,opt,name=map_value,json=mapValue,proto3,oneof"` -} - -type Object_ByteArrayValue struct { - ByteArrayValue []byte `protobuf:"bytes,12,opt,name=byte_array_value,json=byteArrayValue,proto3,oneof"` -} - -type Object_Uint16ArrayValue struct { - Uint16ArrayValue *Uint16S `protobuf:"bytes,13,opt,name=uint16_array_value,json=uint16ArrayValue,proto3,oneof"` -} - -type Object_Uint32ArrayValue struct { - Uint32ArrayValue *Uint32S `protobuf:"bytes,14,opt,name=uint32_array_value,json=uint32ArrayValue,proto3,oneof"` -} - -type Object_Uint64ArrayValue struct { - Uint64ArrayValue *Uint64S `protobuf:"bytes,15,opt,name=uint64_array_value,json=uint64ArrayValue,proto3,oneof"` -} - -type Object_UintptrArrayValue struct { - UintptrArrayValue *Uintptrs `protobuf:"bytes,16,opt,name=uintptr_array_value,json=uintptrArrayValue,proto3,oneof"` -} - -type Object_Int8ArrayValue struct { - Int8ArrayValue *Int8S `protobuf:"bytes,17,opt,name=int8_array_value,json=int8ArrayValue,proto3,oneof"` -} - -type Object_Int16ArrayValue struct { - Int16ArrayValue *Int16S `protobuf:"bytes,18,opt,name=int16_array_value,json=int16ArrayValue,proto3,oneof"` -} - -type Object_Int32ArrayValue struct { - Int32ArrayValue *Int32S `protobuf:"bytes,19,opt,name=int32_array_value,json=int32ArrayValue,proto3,oneof"` -} - -type Object_Int64ArrayValue struct { - Int64ArrayValue *Int64S `protobuf:"bytes,20,opt,name=int64_array_value,json=int64ArrayValue,proto3,oneof"` -} - -type Object_BoolArrayValue struct { - BoolArrayValue *Bools `protobuf:"bytes,21,opt,name=bool_array_value,json=boolArrayValue,proto3,oneof"` -} - -type Object_Float64ArrayValue struct { - Float64ArrayValue *Float64S `protobuf:"bytes,22,opt,name=float64_array_value,json=float64ArrayValue,proto3,oneof"` -} - -type Object_Float32ArrayValue struct { - Float32ArrayValue *Float32S `protobuf:"bytes,23,opt,name=float32_array_value,json=float32ArrayValue,proto3,oneof"` -} - -func (*Object_BoolValue) isObject_Value() {} - -func (*Object_StringValue) isObject_Value() {} - -func (*Object_Int64Value) isObject_Value() {} - -func (*Object_Uint64Value) isObject_Value() {} - -func (*Object_DoubleValue) isObject_Value() {} - -func (*Object_RefValue) isObject_Value() {} - -func (*Object_SliceValue) isObject_Value() {} - -func (*Object_ArrayValue) isObject_Value() {} - -func (*Object_InterfaceValue) isObject_Value() {} - -func (*Object_StructValue) isObject_Value() {} - -func (*Object_MapValue) isObject_Value() {} - -func (*Object_ByteArrayValue) isObject_Value() {} - -func (*Object_Uint16ArrayValue) isObject_Value() {} - -func (*Object_Uint32ArrayValue) isObject_Value() {} - -func (*Object_Uint64ArrayValue) isObject_Value() {} - -func (*Object_UintptrArrayValue) isObject_Value() {} - -func (*Object_Int8ArrayValue) isObject_Value() {} - -func (*Object_Int16ArrayValue) isObject_Value() {} - -func (*Object_Int32ArrayValue) isObject_Value() {} - -func (*Object_Int64ArrayValue) isObject_Value() {} - -func (*Object_BoolArrayValue) isObject_Value() {} - -func (*Object_Float64ArrayValue) isObject_Value() {} - -func (*Object_Float32ArrayValue) isObject_Value() {} - -func (m *Object) GetValue() isObject_Value { - if m != nil { - return m.Value - } - return nil -} - -func (m *Object) GetBoolValue() bool { - if x, ok := m.GetValue().(*Object_BoolValue); ok { - return x.BoolValue - } - return false -} - -func (m *Object) GetStringValue() []byte { - if x, ok := m.GetValue().(*Object_StringValue); ok { - return x.StringValue - } - return nil -} - -func (m *Object) GetInt64Value() int64 { - if x, ok := m.GetValue().(*Object_Int64Value); ok { - return x.Int64Value - } - return 0 -} - -func (m *Object) GetUint64Value() uint64 { - if x, ok := m.GetValue().(*Object_Uint64Value); ok { - return x.Uint64Value - } - return 0 -} - -func (m *Object) GetDoubleValue() float64 { - if x, ok := m.GetValue().(*Object_DoubleValue); ok { - return x.DoubleValue - } - return 0 -} - -func (m *Object) GetRefValue() uint64 { - if x, ok := m.GetValue().(*Object_RefValue); ok { - return x.RefValue - } - return 0 -} - -func (m *Object) GetSliceValue() *Slice { - if x, ok := m.GetValue().(*Object_SliceValue); ok { - return x.SliceValue - } - return nil -} - -func (m *Object) GetArrayValue() *Array { - if x, ok := m.GetValue().(*Object_ArrayValue); ok { - return x.ArrayValue - } - return nil -} - -func (m *Object) GetInterfaceValue() *Interface { - if x, ok := m.GetValue().(*Object_InterfaceValue); ok { - return x.InterfaceValue - } - return nil -} - -func (m *Object) GetStructValue() *Struct { - if x, ok := m.GetValue().(*Object_StructValue); ok { - return x.StructValue - } - return nil -} - -func (m *Object) GetMapValue() *Map { - if x, ok := m.GetValue().(*Object_MapValue); ok { - return x.MapValue - } - return nil -} - -func (m *Object) GetByteArrayValue() []byte { - if x, ok := m.GetValue().(*Object_ByteArrayValue); ok { - return x.ByteArrayValue - } - return nil -} - -func (m *Object) GetUint16ArrayValue() *Uint16S { - if x, ok := m.GetValue().(*Object_Uint16ArrayValue); ok { - return x.Uint16ArrayValue - } - return nil -} - -func (m *Object) GetUint32ArrayValue() *Uint32S { - if x, ok := m.GetValue().(*Object_Uint32ArrayValue); ok { - return x.Uint32ArrayValue - } - return nil -} - -func (m *Object) GetUint64ArrayValue() *Uint64S { - if x, ok := m.GetValue().(*Object_Uint64ArrayValue); ok { - return x.Uint64ArrayValue - } - return nil -} - -func (m *Object) GetUintptrArrayValue() *Uintptrs { - if x, ok := m.GetValue().(*Object_UintptrArrayValue); ok { - return x.UintptrArrayValue - } - return nil -} - -func (m *Object) GetInt8ArrayValue() *Int8S { - if x, ok := m.GetValue().(*Object_Int8ArrayValue); ok { - return x.Int8ArrayValue - } - return nil -} - -func (m *Object) GetInt16ArrayValue() *Int16S { - if x, ok := m.GetValue().(*Object_Int16ArrayValue); ok { - return x.Int16ArrayValue - } - return nil -} - -func (m *Object) GetInt32ArrayValue() *Int32S { - if x, ok := m.GetValue().(*Object_Int32ArrayValue); ok { - return x.Int32ArrayValue - } - return nil -} - -func (m *Object) GetInt64ArrayValue() *Int64S { - if x, ok := m.GetValue().(*Object_Int64ArrayValue); ok { - return x.Int64ArrayValue - } - return nil -} - -func (m *Object) GetBoolArrayValue() *Bools { - if x, ok := m.GetValue().(*Object_BoolArrayValue); ok { - return x.BoolArrayValue - } - return nil -} - -func (m *Object) GetFloat64ArrayValue() *Float64S { - if x, ok := m.GetValue().(*Object_Float64ArrayValue); ok { - return x.Float64ArrayValue - } - return nil -} - -func (m *Object) GetFloat32ArrayValue() *Float32S { - if x, ok := m.GetValue().(*Object_Float32ArrayValue); ok { - return x.Float32ArrayValue - } - return nil -} - -// XXX_OneofWrappers is for the internal use of the proto package. -func (*Object) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*Object_BoolValue)(nil), - (*Object_StringValue)(nil), - (*Object_Int64Value)(nil), - (*Object_Uint64Value)(nil), - (*Object_DoubleValue)(nil), - (*Object_RefValue)(nil), - (*Object_SliceValue)(nil), - (*Object_ArrayValue)(nil), - (*Object_InterfaceValue)(nil), - (*Object_StructValue)(nil), - (*Object_MapValue)(nil), - (*Object_ByteArrayValue)(nil), - (*Object_Uint16ArrayValue)(nil), - (*Object_Uint32ArrayValue)(nil), - (*Object_Uint64ArrayValue)(nil), - (*Object_UintptrArrayValue)(nil), - (*Object_Int8ArrayValue)(nil), - (*Object_Int16ArrayValue)(nil), - (*Object_Int32ArrayValue)(nil), - (*Object_Int64ArrayValue)(nil), - (*Object_BoolArrayValue)(nil), - (*Object_Float64ArrayValue)(nil), - (*Object_Float32ArrayValue)(nil), - } -} - -func init() { - proto.RegisterType((*Slice)(nil), "gvisor.state.statefile.Slice") - proto.RegisterType((*Array)(nil), "gvisor.state.statefile.Array") - proto.RegisterType((*Map)(nil), "gvisor.state.statefile.Map") - proto.RegisterType((*Interface)(nil), "gvisor.state.statefile.Interface") - proto.RegisterType((*Struct)(nil), "gvisor.state.statefile.Struct") - proto.RegisterType((*Field)(nil), "gvisor.state.statefile.Field") - proto.RegisterType((*Uint16S)(nil), "gvisor.state.statefile.Uint16s") - proto.RegisterType((*Uint32S)(nil), "gvisor.state.statefile.Uint32s") - proto.RegisterType((*Uint64S)(nil), "gvisor.state.statefile.Uint64s") - proto.RegisterType((*Uintptrs)(nil), "gvisor.state.statefile.Uintptrs") - proto.RegisterType((*Int8S)(nil), "gvisor.state.statefile.Int8s") - proto.RegisterType((*Int16S)(nil), "gvisor.state.statefile.Int16s") - proto.RegisterType((*Int32S)(nil), "gvisor.state.statefile.Int32s") - proto.RegisterType((*Int64S)(nil), "gvisor.state.statefile.Int64s") - proto.RegisterType((*Bools)(nil), "gvisor.state.statefile.Bools") - proto.RegisterType((*Float64S)(nil), "gvisor.state.statefile.Float64s") - proto.RegisterType((*Float32S)(nil), "gvisor.state.statefile.Float32s") - proto.RegisterType((*Object)(nil), "gvisor.state.statefile.Object") -} - -func init() { proto.RegisterFile("pkg/state/object.proto", fileDescriptor_3dee2c1912d4d62d) } - -var fileDescriptor_3dee2c1912d4d62d = []byte{ - // 781 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x96, 0x6f, 0x4f, 0xda, 0x5e, - 0x14, 0xc7, 0xa9, 0x40, 0x29, 0x07, 0x14, 0xb8, 0xfe, 0x7e, 0x8c, 0xcc, 0x38, 0xb1, 0x7b, 0x42, - 0xf6, 0x00, 0x33, 0x60, 0xc4, 0xf8, 0x64, 0x53, 0x13, 0x03, 0xc9, 0x8c, 0x59, 0x8d, 0xcb, 0x9e, - 0x99, 0x52, 0x2f, 0xac, 0xb3, 0xb6, 0x5d, 0x7b, 0x6b, 0xc2, 0xcb, 0xdc, 0x3b, 0x5a, 0xee, 0x1f, - 0xae, 0xfd, 0x03, 0xc5, 0xec, 0x89, 0xa1, 0xb7, 0xdf, 0xf3, 0xe1, 0xdc, 0xf3, 0x3d, 0xe7, 0x08, - 0xb4, 0xfd, 0xc7, 0xc5, 0x49, 0x48, 0x4c, 0x82, 0x4f, 0xbc, 0xd9, 0x2f, 0x6c, 0x91, 0xbe, 0x1f, - 0x78, 0xc4, 0x43, 0xed, 0xc5, 0xb3, 0x1d, 0x7a, 0x41, 0x9f, 0xbd, 0xe2, 0x7f, 0xe7, 0xb6, 0x83, - 0xf5, 0x1f, 0x50, 0xbe, 0x75, 0x6c, 0x0b, 0xa3, 0x36, 0xa8, 0x0e, 0x76, 0x17, 0xe4, 0x67, 0x47, - 0xe9, 0x2a, 0xbd, 0x5d, 0x43, 0x3c, 0xa1, 0xb7, 0xa0, 0x59, 0xa6, 0x6f, 0x5a, 0x36, 0x59, 0x76, - 0x76, 0xd8, 0x1b, 0xf9, 0x8c, 0x0e, 0xa0, 0x1a, 0xe0, 0xf9, 0xfd, 0xb3, 0xe9, 0x44, 0xb8, 0x53, - 0xec, 0x2a, 0xbd, 0x92, 0xa1, 0x05, 0x78, 0xfe, 0x9d, 0x3e, 0xeb, 0x97, 0x50, 0x3e, 0x0f, 0x02, - 0x73, 0x89, 0xce, 0x40, 0xb3, 0x3c, 0x97, 0x60, 0x97, 0x84, 0x1d, 0xa5, 0x5b, 0xec, 0xd5, 0x06, - 0xef, 0xfa, 0xeb, 0xb3, 0xe9, 0xdf, 0xb0, 0x94, 0x0d, 0xa9, 0xd7, 0x7f, 0x43, 0xf1, 0xda, 0xf4, - 0xd1, 0x00, 0x4a, 0x8f, 0x78, 0xf9, 0xda, 0x70, 0xa6, 0x45, 0x63, 0x50, 0x59, 0x62, 0x61, 0x67, - 0xe7, 0x55, 0x51, 0x42, 0xad, 0xdf, 0x41, 0x75, 0xea, 0x12, 0x1c, 0xcc, 0x4d, 0x0b, 0x23, 0x04, - 0x25, 0xb2, 0xf4, 0x31, 0xab, 0x49, 0xd5, 0x60, 0x9f, 0xd1, 0x08, 0xca, 0xfc, 0xc6, 0xb4, 0x1c, - 0xdb, 0xb9, 0x5c, 0xac, 0x7f, 0x06, 0xf5, 0x96, 0x04, 0x91, 0x45, 0xd0, 0x27, 0x50, 0xe7, 0x36, - 0x76, 0x1e, 0x56, 0xd7, 0x39, 0xdc, 0x04, 0xb8, 0xa2, 0x2a, 0x43, 0x88, 0xf5, 0x6f, 0x50, 0x66, - 0x07, 0x34, 0x27, 0xd7, 0x7c, 0x92, 0x39, 0xd1, 0xcf, 0xff, 0x98, 0xd3, 0x31, 0x54, 0xee, 0x6c, - 0x97, 0x7c, 0x1c, 0x87, 0xd4, 0x7e, 0x51, 0x2d, 0x9a, 0xd4, 0xae, 0xac, 0x86, 0x90, 0x0c, 0x07, - 0x69, 0x49, 0x25, 0x2d, 0x19, 0x8f, 0xd2, 0x12, 0x55, 0x4a, 0x74, 0xd0, 0xa8, 0xc4, 0x27, 0xc1, - 0x66, 0xcd, 0x11, 0x94, 0xa7, 0x2e, 0x39, 0x4d, 0x0a, 0x94, 0x5e, 0x5d, 0x0a, 0xba, 0xa0, 0x4e, - 0xd7, 0x25, 0x5b, 0x4e, 0x29, 0xb2, 0xb9, 0x36, 0x52, 0x8a, 0x6c, 0xaa, 0xcd, 0x78, 0x1a, 0x17, - 0x9e, 0xe7, 0xa4, 0x05, 0x5a, 0xfc, 0x2e, 0x57, 0x8e, 0x67, 0xae, 0x81, 0x28, 0x19, 0x4d, 0x36, - 0x95, 0x1d, 0xa9, 0xf9, 0x53, 0x03, 0x95, 0xdb, 0x81, 0x8e, 0x00, 0x66, 0x9e, 0xe7, 0x88, 0x41, - 0xa2, 0xb7, 0xd6, 0x26, 0x05, 0xa3, 0x4a, 0xcf, 0xd8, 0x2c, 0xa1, 0xf7, 0x50, 0x0f, 0x49, 0x60, - 0xbb, 0x8b, 0xfb, 0x17, 0x97, 0xeb, 0x93, 0x82, 0x51, 0xe3, 0xa7, 0x5c, 0x74, 0x0c, 0x35, 0x66, - 0x43, 0x6c, 0x1e, 0x8b, 0x93, 0x82, 0x01, 0xec, 0x50, 0x72, 0xa2, 0xb8, 0xa6, 0x44, 0x67, 0x96, - 0x72, 0xa2, 0xa4, 0xe8, 0xc1, 0x8b, 0x66, 0x0e, 0x16, 0xa2, 0x72, 0x57, 0xe9, 0x29, 0x54, 0xc4, - 0x4f, 0xb9, 0xe8, 0x30, 0x3e, 0xfa, 0xaa, 0xc0, 0xc8, 0xe1, 0x47, 0x5f, 0xa0, 0x16, 0xd2, 0xb5, - 0x22, 0x04, 0x15, 0xd6, 0x95, 0x1b, 0x1b, 0x9d, 0x6d, 0x20, 0x9a, 0x2a, 0x8b, 0x91, 0x04, 0x93, - 0xae, 0x0f, 0x41, 0xd0, 0xf2, 0x09, 0x6c, 0xd3, 0x50, 0x02, 0x8b, 0xe1, 0x84, 0xaf, 0xd0, 0xb0, - 0x57, 0x83, 0x2c, 0x28, 0x55, 0x46, 0x39, 0xde, 0x44, 0x91, 0x73, 0x3f, 0x29, 0x18, 0x7b, 0x32, - 0x96, 0xd3, 0x2e, 0x99, 0x05, 0x91, 0x45, 0x04, 0x0a, 0xf2, 0x07, 0x8d, 0xcf, 0xba, 0xb0, 0x28, - 0xb2, 0x08, 0x87, 0x9c, 0x41, 0xf5, 0xc9, 0xf4, 0x05, 0xa1, 0xc6, 0x08, 0x07, 0x9b, 0x08, 0xd7, - 0xa6, 0x4f, 0x4b, 0xfa, 0x64, 0xfa, 0x3c, 0xf6, 0x03, 0x34, 0x67, 0x4b, 0x82, 0xef, 0xe3, 0x55, - 0xa9, 0x8b, 0x3e, 0xd8, 0xa3, 0x6f, 0xce, 0x5f, 0xae, 0x7e, 0x03, 0x28, 0x62, 0x83, 0x9d, 0x50, - 0xef, 0xb2, 0x2f, 0x3c, 0xda, 0xf4, 0x85, 0x62, 0x15, 0x4c, 0x0a, 0x46, 0x93, 0x07, 0x67, 0x81, - 0xc3, 0x41, 0x02, 0xb8, 0xb7, 0x1d, 0x38, 0x1c, 0x48, 0xe0, 0x70, 0x90, 0x05, 0x8e, 0x47, 0x09, - 0x60, 0x63, 0x3b, 0x70, 0x3c, 0x92, 0xc0, 0xf1, 0x28, 0x06, 0x34, 0x60, 0x3f, 0xe2, 0x2b, 0x26, - 0x41, 0x6c, 0x32, 0x62, 0x37, 0x8f, 0x48, 0xb7, 0xd2, 0xa4, 0x60, 0xb4, 0x44, 0x78, 0x8c, 0x39, - 0x85, 0xa6, 0xed, 0x92, 0xd3, 0x04, 0xb0, 0x95, 0xdf, 0x88, 0x6c, 0x85, 0x89, 0xf6, 0x39, 0x3d, - 0x8f, 0x37, 0x63, 0x2b, 0x6b, 0x08, 0xca, 0xef, 0xa1, 0xe9, 0xca, 0x8f, 0x46, 0xda, 0x0e, 0x4e, - 0x4b, 0xb9, 0xb1, 0xbf, 0x95, 0xc6, 0xcd, 0x68, 0xa4, 0xbd, 0xe0, 0xb4, 0x94, 0x15, 0xff, 0x6d, - 0xa5, 0x71, 0x27, 0x1a, 0x69, 0x23, 0xa6, 0xd0, 0x64, 0xcb, 0x2c, 0x0e, 0xfb, 0x3f, 0xbf, 0x68, - 0x6c, 0xe1, 0xb2, 0x36, 0xf6, 0x3c, 0x27, 0xe9, 0xe9, 0x9c, 0xaf, 0xda, 0x04, 0xad, 0x9d, 0xef, - 0xe9, 0x6a, 0x3b, 0x53, 0x4f, 0x45, 0xf8, 0x1a, 0x66, 0xaa, 0x78, 0x6f, 0x5e, 0xc1, 0xe4, 0xe5, - 0x6b, 0x89, 0xf0, 0x17, 0xe6, 0x45, 0x45, 0xfc, 0xf7, 0x9d, 0xa9, 0xec, 0xc7, 0xd6, 0xf0, 0x6f, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x84, 0x69, 0xc9, 0x45, 0x86, 0x09, 0x00, 0x00, -} diff --git a/pkg/state/pending_list.go b/pkg/state/pending_list.go new file mode 100644 index 000000000..d30b1b8dc --- /dev/null +++ b/pkg/state/pending_list.go @@ -0,0 +1,178 @@ +package state + +// List is an intrusive list. Entries can be added to or removed from the list +// in O(1) time and with no additional memory allocations. +// +// The zero value for List is an empty list ready to use. +// +// To iterate over a list (where l is a List): +// for e := l.Front(); e != nil; e = e.Next() { +// // do something with e. +// } +// +// +stateify savable +type pendingList struct { + head *objectEncodeState + tail *objectEncodeState +} + +// Reset resets list l to the empty state. +func (l *pendingList) Reset() { + l.head = nil + l.tail = nil +} + +// Empty returns true iff the list is empty. +func (l *pendingList) Empty() bool { + return l.head == nil +} + +// Front returns the first element of list l or nil. +func (l *pendingList) Front() *objectEncodeState { + return l.head +} + +// Back returns the last element of list l or nil. +func (l *pendingList) Back() *objectEncodeState { + return l.tail +} + +// Len returns the number of elements in the list. +// +// NOTE: This is an O(n) operation. +func (l *pendingList) Len() (count int) { + for e := l.Front(); e != nil; e = (pendingMapper{}.linkerFor(e)).Next() { + count++ + } + return count +} + +// PushFront inserts the element e at the front of list l. +func (l *pendingList) PushFront(e *objectEncodeState) { + linker := pendingMapper{}.linkerFor(e) + linker.SetNext(l.head) + linker.SetPrev(nil) + if l.head != nil { + pendingMapper{}.linkerFor(l.head).SetPrev(e) + } else { + l.tail = e + } + + l.head = e +} + +// PushBack inserts the element e at the back of list l. +func (l *pendingList) PushBack(e *objectEncodeState) { + linker := pendingMapper{}.linkerFor(e) + linker.SetNext(nil) + linker.SetPrev(l.tail) + if l.tail != nil { + pendingMapper{}.linkerFor(l.tail).SetNext(e) + } else { + l.head = e + } + + l.tail = e +} + +// PushBackList inserts list m at the end of list l, emptying m. +func (l *pendingList) PushBackList(m *pendingList) { + if l.head == nil { + l.head = m.head + l.tail = m.tail + } else if m.head != nil { + pendingMapper{}.linkerFor(l.tail).SetNext(m.head) + pendingMapper{}.linkerFor(m.head).SetPrev(l.tail) + + l.tail = m.tail + } + m.head = nil + m.tail = nil +} + +// InsertAfter inserts e after b. +func (l *pendingList) InsertAfter(b, e *objectEncodeState) { + bLinker := pendingMapper{}.linkerFor(b) + eLinker := pendingMapper{}.linkerFor(e) + + a := bLinker.Next() + + eLinker.SetNext(a) + eLinker.SetPrev(b) + bLinker.SetNext(e) + + if a != nil { + pendingMapper{}.linkerFor(a).SetPrev(e) + } else { + l.tail = e + } +} + +// InsertBefore inserts e before a. +func (l *pendingList) InsertBefore(a, e *objectEncodeState) { + aLinker := pendingMapper{}.linkerFor(a) + eLinker := pendingMapper{}.linkerFor(e) + + b := aLinker.Prev() + eLinker.SetNext(a) + eLinker.SetPrev(b) + aLinker.SetPrev(e) + + if b != nil { + pendingMapper{}.linkerFor(b).SetNext(e) + } else { + l.head = e + } +} + +// Remove removes e from l. +func (l *pendingList) Remove(e *objectEncodeState) { + linker := pendingMapper{}.linkerFor(e) + prev := linker.Prev() + next := linker.Next() + + if prev != nil { + pendingMapper{}.linkerFor(prev).SetNext(next) + } else if l.head == e { + l.head = next + } + + if next != nil { + pendingMapper{}.linkerFor(next).SetPrev(prev) + } else if l.tail == e { + l.tail = prev + } + + linker.SetNext(nil) + linker.SetPrev(nil) +} + +// Entry is a default implementation of Linker. Users can add anonymous fields +// of this type to their structs to make them automatically implement the +// methods needed by List. +// +// +stateify savable +type pendingEntry struct { + next *objectEncodeState + prev *objectEncodeState +} + +// Next returns the entry that follows e in the list. +func (e *pendingEntry) Next() *objectEncodeState { + return e.next +} + +// Prev returns the entry that precedes e in the list. +func (e *pendingEntry) Prev() *objectEncodeState { + return e.prev +} + +// SetNext assigns 'entry' as the entry that follows e in the list. +func (e *pendingEntry) SetNext(elem *objectEncodeState) { + e.next = elem +} + +// SetPrev assigns 'entry' as the entry that precedes e in the list. +func (e *pendingEntry) SetPrev(elem *objectEncodeState) { + e.prev = elem +} diff --git a/pkg/state/pretty/pretty.go b/pkg/state/pretty/pretty.go new file mode 100644 index 000000000..cf37aaa49 --- /dev/null +++ b/pkg/state/pretty/pretty.go @@ -0,0 +1,273 @@ +// 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 pretty is a pretty-printer for state streams. +package pretty + +import ( + "fmt" + "io" + "io/ioutil" + "reflect" + "strings" + + "gvisor.dev/gvisor/pkg/state" + "gvisor.dev/gvisor/pkg/state/wire" +) + +func formatRef(x *wire.Ref, graph uint64, html bool) string { + baseRef := fmt.Sprintf("g%dr%d", graph, x.Root) + fullRef := baseRef + if len(x.Dots) > 0 { + // See wire.Ref; Type valid if Dots non-zero. + typ, _ := formatType(x.Type, graph, html) + var buf strings.Builder + buf.WriteString("(*") + buf.WriteString(typ) + buf.WriteString(")(") + buf.WriteString(baseRef) + for _, component := range x.Dots { + switch v := component.(type) { + case *wire.FieldName: + buf.WriteString(".") + buf.WriteString(string(*v)) + case wire.Index: + buf.WriteString(fmt.Sprintf("[%d]", v)) + default: + panic(fmt.Sprintf("unreachable: switch should be exhaustive, unhandled case %v", reflect.TypeOf(component))) + } + } + buf.WriteString(")") + fullRef = buf.String() + } + if html { + return fmt.Sprintf("<a href=\"#%s\">%s</a>", baseRef, fullRef) + } + return fullRef +} + +func formatType(t wire.TypeSpec, graph uint64, html bool) (string, bool) { + switch x := t.(type) { + case wire.TypeID: + base := fmt.Sprintf("g%dt%d", graph, x) + if html { + return fmt.Sprintf("<a href=\"#%s\">%s</a>", base, base), true + } + return fmt.Sprintf("%s", base), true + case wire.TypeSpecNil: + return "", false // Only nil type. + case *wire.TypeSpecPointer: + element, _ := formatType(x.Type, graph, html) + return fmt.Sprintf("(*%s)", element), true + case *wire.TypeSpecArray: + element, _ := formatType(x.Type, graph, html) + return fmt.Sprintf("[%d](%s)", x.Count, element), true + case *wire.TypeSpecSlice: + element, _ := formatType(x.Type, graph, html) + return fmt.Sprintf("([]%s)", element), true + case *wire.TypeSpecMap: + key, _ := formatType(x.Key, graph, html) + value, _ := formatType(x.Value, graph, html) + return fmt.Sprintf("(map[%s]%s)", key, value), true + default: + panic(fmt.Sprintf("unreachable: unknown type %T", t)) + } +} + +// format formats a single object, for pretty-printing. It also returns whether +// the value is a non-zero value. +func format(graph uint64, depth int, encoded wire.Object, html bool) (string, bool) { + switch x := encoded.(type) { + case wire.Nil: + return "nil", false + case *wire.String: + return fmt.Sprintf("%q", *x), *x != "" + case *wire.Complex64: + return fmt.Sprintf("%f+%fi", real(*x), imag(*x)), *x != 0.0 + case *wire.Complex128: + return fmt.Sprintf("%f+%fi", real(*x), imag(*x)), *x != 0.0 + case *wire.Ref: + return formatRef(x, graph, html), x.Root != 0 + case *wire.Type: + tabs := "\n" + strings.Repeat("\t", depth) + items := make([]string, 0, len(x.Fields)+2) + items = append(items, fmt.Sprintf("type %s {", x.Name)) + for i := 0; i < len(x.Fields); i++ { + items = append(items, fmt.Sprintf("\t%d: %s,", i, x.Fields[i])) + } + items = append(items, "}") + return strings.Join(items, tabs), true // No zero value. + case *wire.Slice: + return fmt.Sprintf("%s{len:%d,cap:%d}", formatRef(&x.Ref, graph, html), x.Length, x.Capacity), x.Capacity != 0 + case *wire.Array: + if len(x.Contents) == 0 { + return "[]", false + } + items := make([]string, 0, len(x.Contents)+2) + zeros := make([]string, 0) // used to eliminate zero entries. + items = append(items, "[") + tabs := "\n" + strings.Repeat("\t", depth) + for i := 0; i < len(x.Contents); i++ { + item, ok := format(graph, depth+1, x.Contents[i], html) + if !ok { + zeros = append(zeros, fmt.Sprintf("\t%s,", item)) + continue + } + if len(zeros) > 0 { + items = append(items, zeros...) + zeros = nil + } + items = append(items, fmt.Sprintf("\t%s,", item)) + } + if len(zeros) > 0 { + items = append(items, fmt.Sprintf("\t... (%d zeros),", len(zeros))) + } + items = append(items, "]") + return strings.Join(items, tabs), len(zeros) < len(x.Contents) + case *wire.Struct: + typ, _ := formatType(x.TypeID, graph, html) + if x.Fields() == 0 { + return fmt.Sprintf("struct[%s]{}", typ), false + } + items := make([]string, 0, 2) + items = append(items, fmt.Sprintf("struct[%s]{", typ)) + tabs := "\n" + strings.Repeat("\t", depth) + allZero := true + for i := 0; i < x.Fields(); i++ { + element, ok := format(graph, depth+1, *x.Field(i), html) + allZero = allZero && !ok + items = append(items, fmt.Sprintf("\t%d: %s,", i, element)) + i++ + } + items = append(items, "}") + return strings.Join(items, tabs), !allZero + case *wire.Map: + if len(x.Keys) == 0 { + return "map{}", false + } + items := make([]string, 0, len(x.Keys)+2) + items = append(items, "map{") + tabs := "\n" + strings.Repeat("\t", depth) + for i := 0; i < len(x.Keys); i++ { + key, _ := format(graph, depth+1, x.Keys[i], html) + value, _ := format(graph, depth+1, x.Values[i], html) + items = append(items, fmt.Sprintf("\t%s: %s,", key, value)) + } + items = append(items, "}") + return strings.Join(items, tabs), true + case *wire.Interface: + typ, typOk := formatType(x.Type, graph, html) + element, elementOk := format(graph, depth+1, x.Value, html) + return fmt.Sprintf("interface[%s]{%s}", typ, element), typOk || elementOk + default: + // Must be a primitive; use reflection. + return fmt.Sprintf("%v", encoded), true + } +} + +// printStream is the basic print implementation. +func printStream(w io.Writer, r wire.Reader, html bool) (err error) { + // current graph ID. + var graph uint64 + + if html { + fmt.Fprintf(w, "<pre>") + defer fmt.Fprintf(w, "</pre>") + } + + defer func() { + if r := recover(); r != nil { + if rErr, ok := r.(error); ok { + err = rErr // Override return. + return + } + panic(r) // Propagate. + } + }() + + for { + // Find the first object to begin generation. + length, object, err := state.ReadHeader(r) + if err == io.EOF { + // Nothing else to do. + break + } else if err != nil { + return err + } + if !object { + graph++ // Increment the graph. + if length > 0 { + fmt.Fprintf(w, "(%d bytes non-object data)\n", length) + io.Copy(ioutil.Discard, &io.LimitedReader{ + R: r, + N: int64(length), + }) + } + continue + } + + // Read & unmarshal the object. + // + // Note that this loop must match the general structure of the + // loop in decode.go. But we don't register type information, + // etc. and just print the raw structures. + var ( + oid uint64 = 1 + tid uint64 = 1 + ) + for oid <= length { + // Unmarshal the object. + encoded := wire.Load(r) + + // Is this a type? + if _, ok := encoded.(*wire.Type); ok { + str, _ := format(graph, 0, encoded, html) + tag := fmt.Sprintf("g%dt%d", graph, tid) + if html { + // See below. + tag = fmt.Sprintf("<a name=\"%s\">%s</a><a href=\"#%s\">⚓</a>", tag, tag, tag) + } + if _, err := fmt.Fprintf(w, "%s = %s\n", tag, str); err != nil { + return err + } + tid++ + continue + } + + // Format the node. + str, _ := format(graph, 0, encoded, html) + tag := fmt.Sprintf("g%dr%d", graph, oid) + if html { + // Create a little tag with an anchor next to it for linking. + tag = fmt.Sprintf("<a name=\"%s\">%s</a><a href=\"#%s\">⚓</a>", tag, tag, tag) + } + if _, err := fmt.Fprintf(w, "%s = %s\n", tag, str); err != nil { + return err + } + oid++ + } + } + + return nil +} + +// PrintText reads the stream from r and prints text to w. +func PrintText(w io.Writer, r wire.Reader) error { + return printStream(w, r, false /* html */) +} + +// PrintHTML reads the stream from r and prints html to w. +func PrintHTML(w io.Writer, r wire.Reader) error { + return printStream(w, r, true /* html */) +} diff --git a/pkg/gohacks/gohacks_unsafe_state_autogen.go b/pkg/state/pretty/pretty_state_autogen.go index c651ff01e..e772e34a4 100644 --- a/pkg/gohacks/gohacks_unsafe_state_autogen.go +++ b/pkg/state/pretty/pretty_state_autogen.go @@ -1,3 +1,3 @@ // automatically generated by stateify. -package gohacks +package pretty diff --git a/pkg/state/printer.go b/pkg/state/printer.go deleted file mode 100644 index 3ce18242f..000000000 --- a/pkg/state/printer.go +++ /dev/null @@ -1,251 +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 state - -import ( - "fmt" - "io" - "io/ioutil" - "reflect" - "strings" - - "github.com/golang/protobuf/proto" - pb "gvisor.dev/gvisor/pkg/state/object_go_proto" -) - -// format formats a single object, for pretty-printing. It also returns whether -// the value is a non-zero value. -func format(graph uint64, depth int, object *pb.Object, html bool) (string, bool) { - switch x := object.GetValue().(type) { - case *pb.Object_BoolValue: - return fmt.Sprintf("%t", x.BoolValue), x.BoolValue != false - case *pb.Object_StringValue: - return fmt.Sprintf("\"%s\"", string(x.StringValue)), len(x.StringValue) != 0 - case *pb.Object_Int64Value: - return fmt.Sprintf("%d", x.Int64Value), x.Int64Value != 0 - case *pb.Object_Uint64Value: - return fmt.Sprintf("%du", x.Uint64Value), x.Uint64Value != 0 - case *pb.Object_DoubleValue: - return fmt.Sprintf("%f", x.DoubleValue), x.DoubleValue != 0.0 - case *pb.Object_RefValue: - if x.RefValue == 0 { - return "nil", false - } - ref := fmt.Sprintf("g%dr%d", graph, x.RefValue) - if html { - ref = fmt.Sprintf("<a href=#%s>%s</a>", ref, ref) - } - return ref, true - case *pb.Object_SliceValue: - if x.SliceValue.RefValue == 0 { - return "nil", false - } - ref := fmt.Sprintf("g%dr%d", graph, x.SliceValue.RefValue) - if html { - ref = fmt.Sprintf("<a href=#%s>%s</a>", ref, ref) - } - return fmt.Sprintf("%s[:%d:%d]", ref, x.SliceValue.Length, x.SliceValue.Capacity), true - case *pb.Object_ArrayValue: - if len(x.ArrayValue.Contents) == 0 { - return "[]", false - } - items := make([]string, 0, len(x.ArrayValue.Contents)+2) - zeros := make([]string, 0) // used to eliminate zero entries. - items = append(items, "[") - tabs := "\n" + strings.Repeat("\t", depth) - for i := 0; i < len(x.ArrayValue.Contents); i++ { - item, ok := format(graph, depth+1, x.ArrayValue.Contents[i], html) - if ok { - if len(zeros) > 0 { - items = append(items, zeros...) - zeros = nil - } - items = append(items, fmt.Sprintf("\t%s,", item)) - } else { - zeros = append(zeros, fmt.Sprintf("\t%s,", item)) - } - } - if len(zeros) > 0 { - items = append(items, fmt.Sprintf("\t... (%d zeros),", len(zeros))) - } - items = append(items, "]") - return strings.Join(items, tabs), len(zeros) < len(x.ArrayValue.Contents) - case *pb.Object_StructValue: - if len(x.StructValue.Fields) == 0 { - return "struct{}", false - } - items := make([]string, 0, len(x.StructValue.Fields)+2) - items = append(items, "struct{") - tabs := "\n" + strings.Repeat("\t", depth) - allZero := true - for _, field := range x.StructValue.Fields { - element, ok := format(graph, depth+1, field.Value, html) - allZero = allZero && !ok - items = append(items, fmt.Sprintf("\t%s: %s,", field.Name, element)) - } - items = append(items, "}") - return strings.Join(items, tabs), !allZero - case *pb.Object_MapValue: - if len(x.MapValue.Keys) == 0 { - return "map{}", false - } - items := make([]string, 0, len(x.MapValue.Keys)+2) - items = append(items, "map{") - tabs := "\n" + strings.Repeat("\t", depth) - for i := 0; i < len(x.MapValue.Keys); i++ { - key, _ := format(graph, depth+1, x.MapValue.Keys[i], html) - value, _ := format(graph, depth+1, x.MapValue.Values[i], html) - items = append(items, fmt.Sprintf("\t%s: %s,", key, value)) - } - items = append(items, "}") - return strings.Join(items, tabs), true - case *pb.Object_InterfaceValue: - if x.InterfaceValue.Type == "" { - return "interface(nil){}", false - } - element, _ := format(graph, depth+1, x.InterfaceValue.Value, html) - return fmt.Sprintf("interface(\"%s\"){%s}", x.InterfaceValue.Type, element), true - case *pb.Object_ByteArrayValue: - return printArray(reflect.ValueOf(x.ByteArrayValue)) - case *pb.Object_Uint16ArrayValue: - return printArray(reflect.ValueOf(x.Uint16ArrayValue.Values)) - case *pb.Object_Uint32ArrayValue: - return printArray(reflect.ValueOf(x.Uint32ArrayValue.Values)) - case *pb.Object_Uint64ArrayValue: - return printArray(reflect.ValueOf(x.Uint64ArrayValue.Values)) - case *pb.Object_UintptrArrayValue: - return printArray(castSlice(reflect.ValueOf(x.UintptrArrayValue.Values), reflect.TypeOf(uintptr(0)))) - case *pb.Object_Int8ArrayValue: - return printArray(castSlice(reflect.ValueOf(x.Int8ArrayValue.Values), reflect.TypeOf(int8(0)))) - case *pb.Object_Int16ArrayValue: - return printArray(reflect.ValueOf(x.Int16ArrayValue.Values)) - case *pb.Object_Int32ArrayValue: - return printArray(reflect.ValueOf(x.Int32ArrayValue.Values)) - case *pb.Object_Int64ArrayValue: - return printArray(reflect.ValueOf(x.Int64ArrayValue.Values)) - case *pb.Object_BoolArrayValue: - return printArray(reflect.ValueOf(x.BoolArrayValue.Values)) - case *pb.Object_Float64ArrayValue: - return printArray(reflect.ValueOf(x.Float64ArrayValue.Values)) - case *pb.Object_Float32ArrayValue: - return printArray(reflect.ValueOf(x.Float32ArrayValue.Values)) - } - - // Should not happen, but tolerate. - return fmt.Sprintf("(unknown proto type: %T)", object.GetValue()), true -} - -// PrettyPrint reads the state stream from r, and pretty prints to w. -func PrettyPrint(w io.Writer, r io.Reader, html bool) error { - var ( - // current graph ID. - graph uint64 - - // current object ID. - id uint64 - ) - - if html { - fmt.Fprintf(w, "<pre>") - defer fmt.Fprintf(w, "</pre>") - } - - for { - // Find the first object to begin generation. - length, object, err := ReadHeader(r) - if err == io.EOF { - // Nothing else to do. - break - } else if err != nil { - return err - } - if !object { - // Increment the graph number & reset the ID. - graph++ - id = 0 - if length > 0 { - fmt.Fprintf(w, "(%d bytes non-object data)\n", length) - io.Copy(ioutil.Discard, &io.LimitedReader{ - R: r, - N: int64(length), - }) - } - continue - } - - // Read & unmarshal the object. - buf := make([]byte, length) - for done := 0; done < len(buf); { - n, err := r.Read(buf[done:]) - done += n - if n == 0 && err != nil { - return err - } - } - obj := new(pb.Object) - if err := proto.Unmarshal(buf, obj); err != nil { - return err - } - - id++ // First object must be one. - str, _ := format(graph, 0, obj, html) - tag := fmt.Sprintf("g%dr%d", graph, id) - if html { - tag = fmt.Sprintf("<a name=%s>%s</a>", tag, tag) - } - if _, err := fmt.Fprintf(w, "%s = %s\n", tag, str); err != nil { - return err - } - } - - return nil -} - -func printArray(s reflect.Value) (string, bool) { - zero := reflect.Zero(s.Type().Elem()).Interface() - z := "0" - switch s.Type().Elem().Kind() { - case reflect.Bool: - z = "false" - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - case reflect.Float32, reflect.Float64: - default: - return fmt.Sprintf("unexpected non-primitive type array: %#v", s.Interface()), true - } - - zeros := 0 - items := make([]string, 0, s.Len()) - for i := 0; i <= s.Len(); i++ { - if i < s.Len() && reflect.DeepEqual(s.Index(i).Interface(), zero) { - zeros++ - continue - } - if zeros > 0 { - if zeros <= 4 { - for ; zeros > 0; zeros-- { - items = append(items, z) - } - } else { - items = append(items, fmt.Sprintf("(%d %ss)", zeros, z)) - zeros = 0 - } - } - if i < s.Len() { - items = append(items, fmt.Sprintf("%v", s.Index(i).Interface())) - } - } - return "[" + strings.Join(items, ",") + "]", zeros < s.Len() -} diff --git a/pkg/state/state.go b/pkg/state/state.go index 03ae2dbb0..acb629969 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -31,210 +31,226 @@ // Uint64 default // Float32 default // Float64 default -// Complex64 custom -// Complex128 custom +// Complex64 default +// Complex128 default // Array default // Chan custom // Func custom -// Interface custom -// Map default (*) +// Interface default +// Map default // Ptr default // Slice default // String default -// Struct custom +// Struct custom (*) Unless zero-sized. // UnsafePointer custom // -// (*) Maps are treated as value types by this package, even if they are -// pointers internally. If you want to save two independent references -// to the same map value, you must explicitly use a pointer to a map. +// See README.md for an overview of how encoding and decoding works. package state import ( "context" "fmt" - "io" "reflect" "runtime" - pb "gvisor.dev/gvisor/pkg/state/object_go_proto" + "gvisor.dev/gvisor/pkg/state/wire" ) +// objectID is a unique identifier assigned to each object to be serialized. +// Each instance of an object is considered separately, i.e. if there are two +// objects of the same type in the object graph being serialized, they'll be +// assigned unique objectIDs. +type objectID uint32 + +// typeID is the identifier for a type. Types are serialized and tracked +// alongside objects in order to avoid the overhead of encoding field names in +// all objects. +type typeID uint32 + // ErrState is returned when an error is encountered during encode/decode. type ErrState struct { // err is the underlying error. err error - // path is the visit path from root to the current object. - path string - // trace is the stack trace. trace string } // Error returns a sensible description of the state error. func (e *ErrState) Error() string { - return fmt.Sprintf("%v:\nstate path: %s\n%s", e.err, e.path, e.trace) + return fmt.Sprintf("%v:\n%s", e.err, e.trace) } -// UnwrapErrState returns the underlying error in ErrState. -// -// If err is not *ErrState, err is returned directly. -func UnwrapErrState(err error) error { - if e, ok := err.(*ErrState); ok { - return e.err - } - return err +// Unwrap implements standard unwrapping. +func (e *ErrState) Unwrap() error { + return e.err } // Save saves the given object state. -func Save(ctx context.Context, w io.Writer, rootPtr interface{}, stats *Stats) error { +func Save(ctx context.Context, w wire.Writer, rootPtr interface{}) (Stats, error) { // Create the encoding state. - es := &encodeState{ - ctx: ctx, - idsByObject: make(map[uintptr]uint64), - w: w, - stats: stats, + es := encodeState{ + ctx: ctx, + w: w, + types: makeTypeEncodeDatabase(), + zeroValues: make(map[reflect.Type]*objectEncodeState), } // Perform the encoding. - return es.safely(func() { - es.Serialize(reflect.ValueOf(rootPtr).Elem()) + err := safely(func() { + es.Save(reflect.ValueOf(rootPtr).Elem()) }) + return es.stats, err } // Load loads a checkpoint. -func Load(ctx context.Context, r io.Reader, rootPtr interface{}, stats *Stats) error { +func Load(ctx context.Context, r wire.Reader, rootPtr interface{}) (Stats, error) { // Create the decoding state. - ds := &decodeState{ - ctx: ctx, - objectsByID: make(map[uint64]*objectState), - deferred: make(map[uint64]*pb.Object), - r: r, - stats: stats, + ds := decodeState{ + ctx: ctx, + r: r, + types: makeTypeDecodeDatabase(), + deferred: make(map[objectID]wire.Object), } // Attempt our decode. - return ds.safely(func() { - ds.Deserialize(reflect.ValueOf(rootPtr).Elem()) + err := safely(func() { + ds.Load(reflect.ValueOf(rootPtr).Elem()) }) + return ds.stats, err } -// Fns are the state dispatch functions. -type Fns struct { - // Save is a function like Save(concreteType, Map). - Save interface{} - - // Load is a function like Load(concreteType, Map). - Load interface{} +// Sink is used for Type.StateSave. +type Sink struct { + internal objectEncoder } -// Save executes the save function. -func (fns *Fns) invokeSave(obj reflect.Value, m Map) { - reflect.ValueOf(fns.Save).Call([]reflect.Value{obj, reflect.ValueOf(m)}) +// Save adds the given object to the map. +// +// You should pass always pointers to the object you are saving. For example: +// +// type X struct { +// A int +// B *int +// } +// +// func (x *X) StateTypeInfo(m Sink) state.TypeInfo { +// return state.TypeInfo{ +// Name: "pkg.X", +// Fields: []string{ +// "A", +// "B", +// }, +// } +// } +// +// func (x *X) StateSave(m Sink) { +// m.Save(0, &x.A) // Field is A. +// m.Save(1, &x.B) // Field is B. +// } +// +// func (x *X) StateLoad(m Source) { +// m.Load(0, &x.A) // Field is A. +// m.Load(1, &x.B) // Field is B. +// } +func (s Sink) Save(slot int, objPtr interface{}) { + s.internal.save(slot, reflect.ValueOf(objPtr).Elem()) } -// Load executes the load function. -func (fns *Fns) invokeLoad(obj reflect.Value, m Map) { - reflect.ValueOf(fns.Load).Call([]reflect.Value{obj, reflect.ValueOf(m)}) +// SaveValue adds the given object value to the map. +// +// This should be used for values where pointers are not available, or casts +// are required during Save/Load. +// +// For example, if we want to cast external package type P.Foo to int64: +// +// func (x *X) StateSave(m Sink) { +// m.SaveValue(0, "A", int64(x.A)) +// } +// +// func (x *X) StateLoad(m Source) { +// m.LoadValue(0, new(int64), func(x interface{}) { +// x.A = P.Foo(x.(int64)) +// }) +// } +func (s Sink) SaveValue(slot int, obj interface{}) { + s.internal.save(slot, reflect.ValueOf(obj)) } -// validateStateFn ensures types are correct. -func validateStateFn(fn interface{}, typ reflect.Type) bool { - fnTyp := reflect.TypeOf(fn) - if fnTyp.Kind() != reflect.Func { - return false - } - if fnTyp.NumIn() != 2 { - return false - } - if fnTyp.NumOut() != 0 { - return false - } - if fnTyp.In(0) != typ { - return false - } - if fnTyp.In(1) != reflect.TypeOf(Map{}) { - return false - } - return true +// Context returns the context object provided at save time. +func (s Sink) Context() context.Context { + return s.internal.es.ctx } -// Validate validates all state functions. -func (fns *Fns) Validate(typ reflect.Type) bool { - return validateStateFn(fns.Save, typ) && validateStateFn(fns.Load, typ) +// Type is an interface that must be implemented by Struct objects. This allows +// these objects to be serialized while minimizing runtime reflection required. +// +// All these methods can be automatically generated by the go_statify tool. +type Type interface { + // StateTypeName returns the type's name. + // + // This is used for matching type information during encoding and + // decoding, as well as dynamic interface dispatch. This should be + // globally unique. + StateTypeName() string + + // StateFields returns information about the type. + // + // Fields is the set of fields for the object. Calls to Sink.Save and + // Source.Load must be made in-order with respect to these fields. + // + // This will be called at most once per serialization. + StateFields() []string } -type typeDatabase struct { - // nameToType is a forward lookup table. - nameToType map[string]reflect.Type - - // typeToName is the reverse lookup table. - typeToName map[reflect.Type]string +// SaverLoader must be implemented by struct types. +type SaverLoader interface { + // StateSave saves the state of the object to the given Map. + StateSave(Sink) - // typeToFns is the function lookup table. - typeToFns map[reflect.Type]Fns + // StateLoad loads the state of the object. + StateLoad(Source) } -// registeredTypes is a database used for SaveInterface and LoadInterface. -var registeredTypes = typeDatabase{ - nameToType: make(map[string]reflect.Type), - typeToName: make(map[reflect.Type]string), - typeToFns: make(map[reflect.Type]Fns), +// Source is used for Type.StateLoad. +type Source struct { + internal objectDecoder } -// register registers a type under the given name. This will generally be -// called via init() methods, and therefore uses panic to propagate errors. -func (t *typeDatabase) register(name string, typ reflect.Type, fns Fns) { - // We can't allow name collisions. - if ot, ok := t.nameToType[name]; ok { - panic(fmt.Sprintf("type %q can't use name %q, already in use by type %q", typ.Name(), name, ot.Name())) - } - - // Or multiple registrations. - if on, ok := t.typeToName[typ]; ok { - panic(fmt.Sprintf("type %q can't be registered as %q, already registered as %q", typ.Name(), name, on)) - } - - t.nameToType[name] = typ - t.typeToName[typ] = name - t.typeToFns[typ] = fns +// Load loads the given object passed as a pointer.. +// +// See Sink.Save for an example. +func (s Source) Load(slot int, objPtr interface{}) { + s.internal.load(slot, reflect.ValueOf(objPtr), false, nil) } -// lookupType finds a type given a name. -func (t *typeDatabase) lookupType(name string) (reflect.Type, bool) { - typ, ok := t.nameToType[name] - return typ, ok +// LoadWait loads the given objects from the map, and marks it as requiring all +// AfterLoad executions to complete prior to running this object's AfterLoad. +// +// See Sink.Save for an example. +func (s Source) LoadWait(slot int, objPtr interface{}) { + s.internal.load(slot, reflect.ValueOf(objPtr), true, nil) } -// lookupName finds a name given a type. -func (t *typeDatabase) lookupName(typ reflect.Type) (string, bool) { - name, ok := t.typeToName[typ] - return name, ok +// LoadValue loads the given object value from the map. +// +// See Sink.SaveValue for an example. +func (s Source) LoadValue(slot int, objPtr interface{}, fn func(interface{})) { + o := reflect.ValueOf(objPtr) + s.internal.load(slot, o, true, func() { fn(o.Elem().Interface()) }) } -// lookupFns finds functions given a type. -func (t *typeDatabase) lookupFns(typ reflect.Type) (Fns, bool) { - fns, ok := t.typeToFns[typ] - return fns, ok +// AfterLoad schedules a function execution when all objects have been +// allocated and their automated loading and customized load logic have been +// executed. fn will not be executed until all of current object's +// dependencies' AfterLoad() logic, if exist, have been executed. +func (s Source) AfterLoad(fn func()) { + s.internal.afterLoad(fn) } -// Register must be called for any interface implementation types that -// implements Loader. -// -// Register should be called either immediately after startup or via init() -// methods. Double registration of either names or types will result in a panic. -// -// No synchronization is provided; this should only be called in init. -// -// Example usage: -// -// state.Register("Foo", (*Foo)(nil), state.Fns{ -// Save: (*Foo).Save, -// Load: (*Foo).Load, -// }) -// -func Register(name string, instance interface{}, fns Fns) { - registeredTypes.register(name, reflect.TypeOf(instance), fns) +// Context returns the context object provided at load time. +func (s Source) Context() context.Context { + return s.internal.ds.ctx } // IsZeroValue checks if the given value is the zero value. @@ -244,72 +260,14 @@ func IsZeroValue(val interface{}) bool { return val == nil || reflect.ValueOf(val).Elem().IsZero() } -// step captures one encoding / decoding step. On each step, there is up to one -// choice made, which is captured by non-nil param. We intentionally do not -// eagerly create the final path string, as that will only be needed upon panic. -type step struct { - // dereference indicate if the current object is obtained by - // dereferencing a pointer. - dereference bool - - // format is the formatting string that takes param below, if - // non-nil. For example, in array indexing case, we have "[%d]". - format string - - // param stores the choice made at the current encoding / decoding step. - // For eaxmple, in array indexing case, param stores the index. When no - // choice is made, e.g. dereference, param should be nil. - param interface{} -} - -// recoverable is the state encoding / decoding panic recovery facility. It is -// also used to store encoding / decoding steps as well as the reference to the -// original queued object from which the current object is dispatched. The -// complete encoding / decoding path is synthesised from the steps in all queued -// objects leading to the current object. -type recoverable struct { - from *recoverable - steps []step +// Failf is a wrapper around panic that should be used to generate errors that +// can be caught during saving and loading. +func Failf(fmtStr string, v ...interface{}) { + panic(fmt.Errorf(fmtStr, v...)) } -// push enters a new context level. -func (sr *recoverable) push(dereference bool, format string, param interface{}) { - sr.steps = append(sr.steps, step{dereference, format, param}) -} - -// pop exits the current context level. -func (sr *recoverable) pop() { - if len(sr.steps) <= 1 { - return - } - sr.steps = sr.steps[:len(sr.steps)-1] -} - -// path returns the complete encoding / decoding path from root. This is only -// called upon panic. -func (sr *recoverable) path() string { - if sr.from == nil { - return "root" - } - p := sr.from.path() - for _, s := range sr.steps { - if s.dereference { - p = fmt.Sprintf("*(%s)", p) - } - if s.param == nil { - p += s.format - } else { - p += fmt.Sprintf(s.format, s.param) - } - } - return p -} - -func (sr *recoverable) copy() recoverable { - return recoverable{from: sr.from, steps: append([]step(nil), sr.steps...)} -} - -// safely executes the given function, catching a panic and unpacking as an error. +// safely executes the given function, catching a panic and unpacking as an +// error. // // The error flow through the state package uses panic and recover. There are // two important reasons for this: @@ -323,9 +281,15 @@ func (sr *recoverable) copy() recoverable { // method doesn't add a lot of value. If there are specific error conditions // that you'd like to handle, you should add appropriate functionality to // objects themselves prior to calling Save() and Load(). -func (sr *recoverable) safely(fn func()) (err error) { +func safely(fn func()) (err error) { defer func() { if r := recover(); r != nil { + if es, ok := r.(*ErrState); ok { + err = es // Propagate. + return + } + + // Build a new state error. es := new(ErrState) if e, ok := r.(error); ok { es.err = e @@ -333,8 +297,6 @@ func (sr *recoverable) safely(fn func()) (err error) { es.err = fmt.Errorf("%v", r) } - es.path = sr.path() - // Make a stack. We don't know how big it will be ahead // of time, but want to make sure we get the whole // thing. So we just do a stupid brute force approach. diff --git a/pkg/state/state_norace.go b/pkg/state/state_norace.go new file mode 100644 index 000000000..4281aed6d --- /dev/null +++ b/pkg/state/state_norace.go @@ -0,0 +1,19 @@ +// Copyright 2020 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. + +// +build !race + +package state + +var raceEnabled = false diff --git a/pkg/state/state_race.go b/pkg/state/state_race.go new file mode 100644 index 000000000..8232981ce --- /dev/null +++ b/pkg/state/state_race.go @@ -0,0 +1,19 @@ +// Copyright 2020 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. + +// +build race + +package state + +var raceEnabled = true diff --git a/pkg/state/statefile/statefile.go b/pkg/state/statefile/statefile.go index c0f4c4954..bdfb800fb 100644 --- a/pkg/state/statefile/statefile.go +++ b/pkg/state/statefile/statefile.go @@ -57,6 +57,7 @@ import ( "gvisor.dev/gvisor/pkg/binary" "gvisor.dev/gvisor/pkg/compressio" + "gvisor.dev/gvisor/pkg/state/wire" ) // keySize is the AES-256 key length. @@ -83,10 +84,16 @@ var ErrInvalidMetadataLength = fmt.Errorf("metadata length invalid, maximum size // ErrMetadataInvalid is returned if passed metadata is invalid. var ErrMetadataInvalid = fmt.Errorf("metadata invalid, can't start with _") +// WriteCloser is an io.Closer and wire.Writer. +type WriteCloser interface { + wire.Writer + io.Closer +} + // NewWriter returns a state data writer for a statefile. // // Note that the returned WriteCloser must be closed. -func NewWriter(w io.Writer, key []byte, metadata map[string]string) (io.WriteCloser, error) { +func NewWriter(w io.Writer, key []byte, metadata map[string]string) (WriteCloser, error) { if metadata == nil { metadata = make(map[string]string) } @@ -215,7 +222,7 @@ func metadata(r io.Reader, h hash.Hash) (map[string]string, error) { } // NewReader returns a reader for a statefile. -func NewReader(r io.Reader, key []byte) (io.Reader, map[string]string, error) { +func NewReader(r io.Reader, key []byte) (wire.Reader, map[string]string, error) { // Read the metadata with the hash. h := hmac.New(sha256.New, key) metadata, err := metadata(r, h) @@ -224,9 +231,9 @@ func NewReader(r io.Reader, key []byte) (io.Reader, map[string]string, error) { } // Wrap in compression. - rc, err := compressio.NewReader(r, key) + cr, err := compressio.NewReader(r, key) if err != nil { return nil, nil, err } - return rc, metadata, nil + return cr, metadata, nil } diff --git a/pkg/state/stats.go b/pkg/state/stats.go index eb51cda47..eaec664a1 100644 --- a/pkg/state/stats.go +++ b/pkg/state/stats.go @@ -17,7 +17,6 @@ package state import ( "bytes" "fmt" - "reflect" "sort" "time" ) @@ -35,92 +34,81 @@ type statEntry struct { // All exported receivers accept nil. type Stats struct { // byType contains a breakdown of time spent by type. - byType map[reflect.Type]*statEntry + // + // This is indexed *directly* by typeID, including zero. + byType []statEntry // stack contains objects in progress. - stack []reflect.Type + stack []typeID + + // names contains type names. + // + // This is also indexed *directly* by typeID, including zero, which we + // hard-code as "state.default". This is only resolved by calling fini + // on the stats object. + names []string // last is the last start time. last time.Time } -// sample adds the samples to the given object. -func (s *Stats) sample(typ reflect.Type) { - now := time.Now() - s.byType[typ].total += now.Sub(s.last) - s.last = now +// init initializes statistics. +func (s *Stats) init() { + s.last = time.Now() + s.stack = append(s.stack, 0) } -// Add adds a sample count. -func (s *Stats) Add(obj reflect.Value) { - if s == nil { - return - } - if s.byType == nil { - s.byType = make(map[reflect.Type]*statEntry) - } - typ := obj.Type() - entry, ok := s.byType[typ] - if !ok { - entry = new(statEntry) - s.byType[typ] = entry +// fini finalizes statistics. +func (s *Stats) fini(resolve func(id typeID) string) { + s.done() + + // Resolve all type names. + s.names = make([]string, len(s.byType)) + s.names[0] = "state.default" // See above. + for id := typeID(1); int(id) < len(s.names); id++ { + s.names[id] = resolve(id) } - entry.count++ } -// Remove removes a sample count. It should only be called after a previous -// Add(). -func (s *Stats) Remove(obj reflect.Value) { - if s == nil { - return +// sample adds the samples to the given object. +func (s *Stats) sample(id typeID) { + now := time.Now() + if len(s.byType) <= int(id) { + // Allocate all the missing entries in one fell swoop. + s.byType = append(s.byType, make([]statEntry, 1+int(id)-len(s.byType))...) } - typ := obj.Type() - entry := s.byType[typ] - entry.count-- + s.byType[id].total += now.Sub(s.last) + s.last = now } -// Start starts a sample. -func (s *Stats) Start(obj reflect.Value) { - if s == nil { - return - } - if len(s.stack) > 0 { - last := s.stack[len(s.stack)-1] - s.sample(last) - } else { - // First time sample. - s.last = time.Now() - } - s.stack = append(s.stack, obj.Type()) +// start starts a sample. +func (s *Stats) start(id typeID) { + last := s.stack[len(s.stack)-1] + s.sample(last) + s.stack = append(s.stack, id) } -// Done finishes the current sample. -func (s *Stats) Done() { - if s == nil { - return - } +// done finishes the current sample. +func (s *Stats) done() { last := s.stack[len(s.stack)-1] s.sample(last) + s.byType[last].count++ s.stack = s.stack[:len(s.stack)-1] } type sliceEntry struct { - typ reflect.Type + name string entry *statEntry } // String returns a table representation of the stats. func (s *Stats) String() string { - if s == nil || len(s.byType) == 0 { - return "(no data)" - } - // Build a list of stat entries. ss := make([]sliceEntry, 0, len(s.byType)) - for typ, entry := range s.byType { + for id := 0; id < len(s.names); id++ { ss = append(ss, sliceEntry{ - typ: typ, - entry: entry, + name: s.names[id], + entry: &s.byType[id], }) } @@ -136,17 +124,22 @@ func (s *Stats) String() string { total time.Duration ) buf.WriteString("\n") - buf.WriteString(fmt.Sprintf("%12s | %8s | %8s | %s\n", "total", "count", "per", "type")) - buf.WriteString("-------------+----------+----------+-------------\n") + buf.WriteString(fmt.Sprintf("% 16s | % 8s | % 16s | %s\n", "total", "count", "per", "type")) + buf.WriteString("-----------------+----------+------------------+----------------\n") for _, se := range ss { + if se.entry.count == 0 { + // Since we store all types linearly, we are not + // guaranteed that any entry actually has time. + continue + } count += se.entry.count total += se.entry.total per := se.entry.total / time.Duration(se.entry.count) - buf.WriteString(fmt.Sprintf("%12s | %8d | %8s | %s\n", - se.entry.total, se.entry.count, per, se.typ.String())) + buf.WriteString(fmt.Sprintf("% 16s | %8d | % 16s | %s\n", + se.entry.total, se.entry.count, per, se.name)) } - buf.WriteString("-------------+----------+----------+-------------\n") - buf.WriteString(fmt.Sprintf("%12s | %8d | %8s | [all]", + buf.WriteString("-----------------+----------+------------------+----------------\n") + buf.WriteString(fmt.Sprintf("% 16s | % 8d | % 16s | [all]", total, count, total/time.Duration(count))) return string(buf.Bytes()) } diff --git a/pkg/state/types.go b/pkg/state/types.go new file mode 100644 index 000000000..215ef80f8 --- /dev/null +++ b/pkg/state/types.go @@ -0,0 +1,361 @@ +// Copyright 2020 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 state + +import ( + "reflect" + "sort" + + "gvisor.dev/gvisor/pkg/state/wire" +) + +// assertValidType asserts that the type is valid. +func assertValidType(name string, fields []string) { + if name == "" { + Failf("type has empty name") + } + fieldsCopy := make([]string, len(fields)) + for i := 0; i < len(fields); i++ { + if fields[i] == "" { + Failf("field has empty name for type %q", name) + } + fieldsCopy[i] = fields[i] + } + sort.Slice(fieldsCopy, func(i, j int) bool { + return fieldsCopy[i] < fieldsCopy[j] + }) + for i := range fieldsCopy { + if i > 0 && fieldsCopy[i-1] == fieldsCopy[i] { + Failf("duplicate field %q for type %s", fieldsCopy[i], name) + } + } +} + +// typeEntry is an entry in the typeDatabase. +type typeEntry struct { + ID typeID + wire.Type +} + +// reconciledTypeEntry is a reconciled entry in the typeDatabase. +type reconciledTypeEntry struct { + wire.Type + LocalType reflect.Type + FieldOrder []int +} + +// typeEncodeDatabase is an internal TypeInfo database for encoding. +type typeEncodeDatabase struct { + // byType maps by type to the typeEntry. + byType map[reflect.Type]*typeEntry + + // lastID is the last used ID. + lastID typeID +} + +// makeTypeEncodeDatabase makes a typeDatabase. +func makeTypeEncodeDatabase() typeEncodeDatabase { + return typeEncodeDatabase{ + byType: make(map[reflect.Type]*typeEntry), + } +} + +// typeDecodeDatabase is an internal TypeInfo database for decoding. +type typeDecodeDatabase struct { + // byID maps by ID to type. + byID []*reconciledTypeEntry + + // pending are entries that are pending validation by Lookup. These + // will be reconciled with actual objects. Note that these will also be + // used to lookup types by name, since they may not be reconciled and + // there's little value to deleting from this map. + pending []*wire.Type +} + +// makeTypeDecodeDatabase makes a typeDatabase. +func makeTypeDecodeDatabase() typeDecodeDatabase { + return typeDecodeDatabase{} +} + +// lookupNameFields extracts the name and fields from an object. +func lookupNameFields(typ reflect.Type) (string, []string, bool) { + v := reflect.Zero(reflect.PtrTo(typ)).Interface() + t, ok := v.(Type) + if !ok { + // Is this a primitive? + if typ.Kind() == reflect.Interface { + return interfaceType, nil, true + } + name := typ.Name() + if _, ok := primitiveTypeDatabase[name]; !ok { + // This is not a known type, and not a primitive. The + // encoder may proceed for anonymous empty structs, or + // it may deference the type pointer and try again. + return "", nil, false + } + return name, nil, true + } + // Extract the name from the object. + name := t.StateTypeName() + fields := t.StateFields() + assertValidType(name, fields) + return name, fields, true +} + +// Lookup looks up or registers the given object. +// +// The bool indicates whether this is an existing entry: false means the entry +// did not exist, and true means the entry did exist. If this bool is false and +// the returned typeEntry are nil, then the obj did not implement the Type +// interface. +func (tdb *typeEncodeDatabase) Lookup(typ reflect.Type) (*typeEntry, bool) { + te, ok := tdb.byType[typ] + if !ok { + // Lookup the type information. + name, fields, ok := lookupNameFields(typ) + if !ok { + // Empty structs may still be encoded, so let the + // caller decide what to do from here. + return nil, false + } + + // Register the new type. + tdb.lastID++ + te = &typeEntry{ + ID: tdb.lastID, + Type: wire.Type{ + Name: name, + Fields: fields, + }, + } + + // All done. + tdb.byType[typ] = te + return te, false + } + return te, true +} + +// Register adds a typeID entry. +func (tbd *typeDecodeDatabase) Register(typ *wire.Type) { + assertValidType(typ.Name, typ.Fields) + tbd.pending = append(tbd.pending, typ) +} + +// LookupName looks up the type name by ID. +func (tbd *typeDecodeDatabase) LookupName(id typeID) string { + if len(tbd.pending) < int(id) { + // This is likely an encoder error? + Failf("type ID %d not available", id) + } + return tbd.pending[id-1].Name +} + +// LookupType looks up the type by ID. +func (tbd *typeDecodeDatabase) LookupType(id typeID) reflect.Type { + name := tbd.LookupName(id) + typ, ok := globalTypeDatabase[name] + if !ok { + // If not available, see if it's primitive. + typ, ok = primitiveTypeDatabase[name] + if !ok && name == interfaceType { + // Matches the built-in interface type. + var i interface{} + return reflect.TypeOf(&i).Elem() + } + if !ok { + // The type is perhaps not registered? + Failf("type name %q is not available", name) + } + return typ // Primitive type. + } + return typ // Registered type. +} + +// singleFieldOrder defines the field order for a single field. +var singleFieldOrder = []int{0} + +// Lookup looks up or registers the given object. +// +// First, the typeID is searched to see if this has already been appropriately +// reconciled. If no, then a reconcilation will take place that may result in a +// field ordering. If a nil reconciledTypeEntry is returned from this method, +// then the object does not support the Type interface. +// +// This method never returns nil. +func (tbd *typeDecodeDatabase) Lookup(id typeID, typ reflect.Type) *reconciledTypeEntry { + if len(tbd.byID) > int(id) && tbd.byID[id-1] != nil { + // Already reconciled. + return tbd.byID[id-1] + } + // The ID has not been reconciled yet. That's fine. We need to make + // sure it aligns with the current provided object. + if len(tbd.pending) < int(id) { + // This id was never registered. Probably an encoder error? + Failf("typeDatabase does not contain id %d", id) + } + // Extract the pending info. + pending := tbd.pending[id-1] + // Grow the byID list. + if len(tbd.byID) < int(id) { + tbd.byID = append(tbd.byID, make([]*reconciledTypeEntry, int(id)-len(tbd.byID))...) + } + // Reconcile the type. + name, fields, ok := lookupNameFields(typ) + if !ok { + // Empty structs are decoded only when the type is nil. Since + // this isn't the case, we fail here. + Failf("unsupported type %q during decode; can't reconcile", pending.Name) + } + if name != pending.Name { + // Are these the same type? Print a helpful message as this may + // actually happen in practice if types change. + Failf("typeDatabase contains conflicting definitions for id %d: %s->%v (current) and %s->%v (existing)", + id, name, fields, pending.Name, pending.Fields) + } + rte := &reconciledTypeEntry{ + Type: wire.Type{ + Name: name, + Fields: fields, + }, + LocalType: typ, + } + // If there are zero or one fields, then we skip allocating the field + // slice. There is special handling for decoding in this case. If the + // field name does not match, it will be caught in the general purpose + // code below. + if len(fields) != len(pending.Fields) { + Failf("type %q contains different fields: %v (decode) and %v (encode)", + name, fields, pending.Fields) + } + if len(fields) == 0 { + tbd.byID[id-1] = rte // Save. + return rte + } + if len(fields) == 1 && fields[0] == pending.Fields[0] { + tbd.byID[id-1] = rte // Save. + rte.FieldOrder = singleFieldOrder + return rte + } + // For each field in the current object's information, match it to a + // field in the destination object. We know from the assertion above + // and the insertion on insertion to pending that neither field + // contains any duplicates. + fieldOrder := make([]int, len(fields)) + for i, name := range fields { + fieldOrder[i] = -1 // Sentinel. + // Is it an exact match? + if pending.Fields[i] == name { + fieldOrder[i] = i + continue + } + // Find the matching field. + for j, otherName := range pending.Fields { + if name == otherName { + fieldOrder[i] = j + break + } + } + if fieldOrder[i] == -1 { + // The type name matches but we are lacking some common fields. + Failf("type %q has mismatched fields: %v (decode) and %v (encode)", + name, fields, pending.Fields) + } + } + // The type has been reeconciled. + rte.FieldOrder = fieldOrder + tbd.byID[id-1] = rte + return rte +} + +// interfaceType defines all interfaces. +const interfaceType = "interface" + +// primitiveTypeDatabase is a set of fixed types. +var primitiveTypeDatabase = func() map[string]reflect.Type { + r := make(map[string]reflect.Type) + for _, t := range []reflect.Type{ + reflect.TypeOf(false), + reflect.TypeOf(int(0)), + reflect.TypeOf(int8(0)), + reflect.TypeOf(int16(0)), + reflect.TypeOf(int32(0)), + reflect.TypeOf(int64(0)), + reflect.TypeOf(uint(0)), + reflect.TypeOf(uintptr(0)), + reflect.TypeOf(uint8(0)), + reflect.TypeOf(uint16(0)), + reflect.TypeOf(uint32(0)), + reflect.TypeOf(uint64(0)), + reflect.TypeOf(""), + reflect.TypeOf(float32(0.0)), + reflect.TypeOf(float64(0.0)), + reflect.TypeOf(complex64(0.0)), + reflect.TypeOf(complex128(0.0)), + } { + r[t.Name()] = t + } + return r +}() + +// globalTypeDatabase is used for dispatching interfaces on decode. +var globalTypeDatabase = map[string]reflect.Type{} + +// Register registers a type. +// +// This must be called on init and only done once. +func Register(t Type) { + name := t.StateTypeName() + fields := t.StateFields() + assertValidType(name, fields) + // Register must always be called on pointers. + typ := reflect.TypeOf(t) + if typ.Kind() != reflect.Ptr { + Failf("Register must be called on pointers") + } + typ = typ.Elem() + if typ.Kind() == reflect.Struct { + // All registered structs must implement SaverLoader. We allow + // the registration is non-struct types with just the Type + // interface, but we need to call StateSave/StateLoad methods + // on aggregate types. + if _, ok := t.(SaverLoader); !ok { + Failf("struct %T does not implement SaverLoader", t) + } + } else { + // Non-structs must not have any fields. We don't support + // calling StateSave/StateLoad methods on any non-struct types. + // If custom behavior is required, these types should be + // wrapped in a structure of some kind. + if len(fields) != 0 { + Failf("non-struct %T has non-zero fields %v", t, fields) + } + // We don't allow non-structs to implement StateSave/StateLoad + // methods, because they won't be called and it's confusing. + if _, ok := t.(SaverLoader); ok { + Failf("non-struct %T implements SaverLoader", t) + } + } + if _, ok := primitiveTypeDatabase[name]; ok { + Failf("conflicting primitiveTypeDatabase entry for %T: used by primitive", t) + } + if _, ok := globalTypeDatabase[name]; ok { + Failf("conflicting globalTypeDatabase entries for %T: name conflict", t) + } + if name == interfaceType { + Failf("conflicting name for %T: matches interfaceType", t) + } + globalTypeDatabase[name] = typ +} diff --git a/pkg/state/wire/wire.go b/pkg/state/wire/wire.go new file mode 100644 index 000000000..93dee6740 --- /dev/null +++ b/pkg/state/wire/wire.go @@ -0,0 +1,970 @@ +// Copyright 2020 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 wire contains a few basic types that can be composed to serialize +// graph information for the state package. This package defines the wire +// protocol. +// +// Note that these types are careful about how they implement the relevant +// interfaces (either value receiver or pointer receiver), so that native-sized +// types, such as integers and simple pointers, can fit inside the interface +// object. +// +// This package also uses panic as control flow, so called should be careful to +// wrap calls in appropriate handlers. +// +// Testing for this package is driven by the state test package. +package wire + +import ( + "fmt" + "io" + "math" + + "gvisor.dev/gvisor/pkg/gohacks" +) + +// Reader is the required reader interface. +type Reader interface { + io.Reader + ReadByte() (byte, error) +} + +// Writer is the required writer interface. +type Writer interface { + io.Writer + WriteByte(byte) error +} + +// readFull is a utility. The equivalent is not needed for Write, but the API +// contract dictates that it must always complete all bytes given or return an +// error. +func readFull(r io.Reader, p []byte) { + for done := 0; done < len(p); { + n, err := r.Read(p[done:]) + done += n + if n == 0 && err != nil { + panic(err) + } + } +} + +// Object is a generic object. +type Object interface { + // save saves the given object. + // + // Panic is used for error control flow. + save(Writer) + + // load loads a new object of the given type. + // + // Panic is used for error control flow. + load(Reader) Object +} + +// Bool is a boolean. +type Bool bool + +// loadBool loads an object of type Bool. +func loadBool(r Reader) Bool { + b := loadUint(r) + return Bool(b == 1) +} + +// save implements Object.save. +func (b Bool) save(w Writer) { + var v Uint + if b { + v = 1 + } else { + v = 0 + } + v.save(w) +} + +// load implements Object.load. +func (Bool) load(r Reader) Object { return loadBool(r) } + +// Int is a signed integer. +// +// This uses varint encoding. +type Int int64 + +// loadInt loads an object of type Int. +func loadInt(r Reader) Int { + u := loadUint(r) + x := Int(u >> 1) + if u&1 != 0 { + x = ^x + } + return x +} + +// save implements Object.save. +func (i Int) save(w Writer) { + u := Uint(i) << 1 + if i < 0 { + u = ^u + } + u.save(w) +} + +// load implements Object.load. +func (Int) load(r Reader) Object { return loadInt(r) } + +// Uint is an unsigned integer. +type Uint uint64 + +// loadUint loads an object of type Uint. +func loadUint(r Reader) Uint { + var ( + u Uint + s uint + ) + for i := 0; i <= 9; i++ { + b, err := r.ReadByte() + if err != nil { + panic(err) + } + if b < 0x80 { + if i == 9 && b > 1 { + panic("overflow") + } + u |= Uint(b) << s + return u + } + u |= Uint(b&0x7f) << s + s += 7 + } + panic("unreachable") +} + +// save implements Object.save. +func (u Uint) save(w Writer) { + for u >= 0x80 { + if err := w.WriteByte(byte(u) | 0x80); err != nil { + panic(err) + } + u >>= 7 + } + if err := w.WriteByte(byte(u)); err != nil { + panic(err) + } +} + +// load implements Object.load. +func (Uint) load(r Reader) Object { return loadUint(r) } + +// Float32 is a 32-bit floating point number. +type Float32 float32 + +// loadFloat32 loads an object of type Float32. +func loadFloat32(r Reader) Float32 { + n := loadUint(r) + return Float32(math.Float32frombits(uint32(n))) +} + +// save implements Object.save. +func (f Float32) save(w Writer) { + n := Uint(math.Float32bits(float32(f))) + n.save(w) +} + +// load implements Object.load. +func (Float32) load(r Reader) Object { return loadFloat32(r) } + +// Float64 is a 64-bit floating point number. +type Float64 float64 + +// loadFloat64 loads an object of type Float64. +func loadFloat64(r Reader) Float64 { + n := loadUint(r) + return Float64(math.Float64frombits(uint64(n))) +} + +// save implements Object.save. +func (f Float64) save(w Writer) { + n := Uint(math.Float64bits(float64(f))) + n.save(w) +} + +// load implements Object.load. +func (Float64) load(r Reader) Object { return loadFloat64(r) } + +// Complex64 is a 64-bit complex number. +type Complex64 complex128 + +// loadComplex64 loads an object of type Complex64. +func loadComplex64(r Reader) Complex64 { + re := loadFloat32(r) + im := loadFloat32(r) + return Complex64(complex(float32(re), float32(im))) +} + +// save implements Object.save. +func (c *Complex64) save(w Writer) { + re := Float32(real(*c)) + im := Float32(imag(*c)) + re.save(w) + im.save(w) +} + +// load implements Object.load. +func (*Complex64) load(r Reader) Object { + c := loadComplex64(r) + return &c +} + +// Complex128 is a 128-bit complex number. +type Complex128 complex128 + +// loadComplex128 loads an object of type Complex128. +func loadComplex128(r Reader) Complex128 { + re := loadFloat64(r) + im := loadFloat64(r) + return Complex128(complex(float64(re), float64(im))) +} + +// save implements Object.save. +func (c *Complex128) save(w Writer) { + re := Float64(real(*c)) + im := Float64(imag(*c)) + re.save(w) + im.save(w) +} + +// load implements Object.load. +func (*Complex128) load(r Reader) Object { + c := loadComplex128(r) + return &c +} + +// String is a string. +type String string + +// loadString loads an object of type String. +func loadString(r Reader) String { + l := loadUint(r) + p := make([]byte, l) + readFull(r, p) + return String(gohacks.StringFromImmutableBytes(p)) +} + +// save implements Object.save. +func (s *String) save(w Writer) { + l := Uint(len(*s)) + l.save(w) + p := gohacks.ImmutableBytesFromString(string(*s)) + _, err := w.Write(p) // Must write all bytes. + if err != nil { + panic(err) + } +} + +// load implements Object.load. +func (*String) load(r Reader) Object { + s := loadString(r) + return &s +} + +// Dot is a kind of reference: one of Index and FieldName. +type Dot interface { + isDot() +} + +// Index is a reference resolution. +type Index uint32 + +func (Index) isDot() {} + +// FieldName is a reference resolution. +type FieldName string + +func (*FieldName) isDot() {} + +// Ref is a reference to an object. +type Ref struct { + // Root is the root object. + Root Uint + + // Dots is the set of traversals required from the Root object above. + // Note that this will be stored in reverse order for efficiency. + Dots []Dot + + // Type is the base type for the root object. This is non-nil iff Dots + // is non-zero length (that is, this is a complex reference). This is + // not *strictly* necessary, but can be used to simplify decoding. + Type TypeSpec +} + +// loadRef loads an object of type Ref (abstract). +func loadRef(r Reader) Ref { + ref := Ref{ + Root: loadUint(r), + } + l := loadUint(r) + ref.Dots = make([]Dot, l) + for i := 0; i < int(l); i++ { + // Disambiguate between an Index (non-negative) and a field + // name (negative). This does some space and avoids a dedicate + // loadDot function. See Ref.save for the other side. + d := loadInt(r) + if d >= 0 { + ref.Dots[i] = Index(d) + continue + } + p := make([]byte, -d) + readFull(r, p) + fieldName := FieldName(gohacks.StringFromImmutableBytes(p)) + ref.Dots[i] = &fieldName + } + if l != 0 { + // Only if dots is non-zero. + ref.Type = loadTypeSpec(r) + } + return ref +} + +// save implements Object.save. +func (r *Ref) save(w Writer) { + r.Root.save(w) + l := Uint(len(r.Dots)) + l.save(w) + for _, d := range r.Dots { + // See LoadRef. We use non-negative numbers to encode Index + // objects and negative numbers to encode field lengths. + switch x := d.(type) { + case Index: + i := Int(x) + i.save(w) + case *FieldName: + d := Int(-len(*x)) + d.save(w) + p := gohacks.ImmutableBytesFromString(string(*x)) + if _, err := w.Write(p); err != nil { + panic(err) + } + default: + panic("unknown dot implementation") + } + } + if l != 0 { + // See above. + saveTypeSpec(w, r.Type) + } +} + +// load implements Object.load. +func (*Ref) load(r Reader) Object { + ref := loadRef(r) + return &ref +} + +// Nil is a primitive zero value of any type. +type Nil struct{} + +// loadNil loads an object of type Nil. +func loadNil(r Reader) Nil { + return Nil{} +} + +// save implements Object.save. +func (Nil) save(w Writer) {} + +// load implements Object.load. +func (Nil) load(r Reader) Object { return loadNil(r) } + +// Slice is a slice value. +type Slice struct { + Length Uint + Capacity Uint + Ref Ref +} + +// loadSlice loads an object of type Slice. +func loadSlice(r Reader) Slice { + return Slice{ + Length: loadUint(r), + Capacity: loadUint(r), + Ref: loadRef(r), + } +} + +// save implements Object.save. +func (s *Slice) save(w Writer) { + s.Length.save(w) + s.Capacity.save(w) + s.Ref.save(w) +} + +// load implements Object.load. +func (*Slice) load(r Reader) Object { + s := loadSlice(r) + return &s +} + +// Array is an array value. +type Array struct { + Contents []Object +} + +// loadArray loads an object of type Array. +func loadArray(r Reader) Array { + l := loadUint(r) + if l == 0 { + // Note that there isn't a single object available to encode + // the type of, so we need this additional branch. + return Array{} + } + // All the objects here have the same type, so use dynamic dispatch + // only once. All other objects will automatically take the same type + // as the first object. + contents := make([]Object, l) + v := Load(r) + contents[0] = v + for i := 1; i < int(l); i++ { + contents[i] = v.load(r) + } + return Array{ + Contents: contents, + } +} + +// save implements Object.save. +func (a *Array) save(w Writer) { + l := Uint(len(a.Contents)) + l.save(w) + if l == 0 { + // See LoadArray. + return + } + // See above. + Save(w, a.Contents[0]) + for i := 1; i < int(l); i++ { + a.Contents[i].save(w) + } +} + +// load implements Object.load. +func (*Array) load(r Reader) Object { + a := loadArray(r) + return &a +} + +// Map is a map value. +type Map struct { + Keys []Object + Values []Object +} + +// loadMap loads an object of type Map. +func loadMap(r Reader) Map { + l := loadUint(r) + if l == 0 { + // See LoadArray. + return Map{} + } + // See type dispatch notes in Array. + keys := make([]Object, l) + values := make([]Object, l) + k := Load(r) + v := Load(r) + keys[0] = k + values[0] = v + for i := 1; i < int(l); i++ { + keys[i] = k.load(r) + values[i] = v.load(r) + } + return Map{ + Keys: keys, + Values: values, + } +} + +// save implements Object.save. +func (m *Map) save(w Writer) { + l := Uint(len(m.Keys)) + if int(l) != len(m.Values) { + panic(fmt.Sprintf("mismatched keys (%d) Aand values (%d)", len(m.Keys), len(m.Values))) + } + l.save(w) + if l == 0 { + // See LoadArray. + return + } + // See above. + Save(w, m.Keys[0]) + Save(w, m.Values[0]) + for i := 1; i < int(l); i++ { + m.Keys[i].save(w) + m.Values[i].save(w) + } +} + +// load implements Object.load. +func (*Map) load(r Reader) Object { + m := loadMap(r) + return &m +} + +// TypeSpec is a type dereference. +type TypeSpec interface { + isTypeSpec() +} + +// TypeID is a concrete type ID. +type TypeID Uint + +func (TypeID) isTypeSpec() {} + +// TypeSpecPointer is a pointer type. +type TypeSpecPointer struct { + Type TypeSpec +} + +func (*TypeSpecPointer) isTypeSpec() {} + +// TypeSpecArray is an array type. +type TypeSpecArray struct { + Count Uint + Type TypeSpec +} + +func (*TypeSpecArray) isTypeSpec() {} + +// TypeSpecSlice is a slice type. +type TypeSpecSlice struct { + Type TypeSpec +} + +func (*TypeSpecSlice) isTypeSpec() {} + +// TypeSpecMap is a map type. +type TypeSpecMap struct { + Key TypeSpec + Value TypeSpec +} + +func (*TypeSpecMap) isTypeSpec() {} + +// TypeSpecNil is an empty type. +type TypeSpecNil struct{} + +func (TypeSpecNil) isTypeSpec() {} + +// TypeSpec types. +// +// These use a distinct encoding on the wire, as they are used only in the +// interface object. They are decoded through the dedicated loadTypeSpec and +// saveTypeSpec functions. +const ( + typeSpecTypeID Uint = iota + typeSpecPointer + typeSpecArray + typeSpecSlice + typeSpecMap + typeSpecNil +) + +// loadTypeSpec loads TypeSpec values. +func loadTypeSpec(r Reader) TypeSpec { + switch hdr := loadUint(r); hdr { + case typeSpecTypeID: + return TypeID(loadUint(r)) + case typeSpecPointer: + return &TypeSpecPointer{ + Type: loadTypeSpec(r), + } + case typeSpecArray: + return &TypeSpecArray{ + Count: loadUint(r), + Type: loadTypeSpec(r), + } + case typeSpecSlice: + return &TypeSpecSlice{ + Type: loadTypeSpec(r), + } + case typeSpecMap: + return &TypeSpecMap{ + Key: loadTypeSpec(r), + Value: loadTypeSpec(r), + } + case typeSpecNil: + return TypeSpecNil{} + default: + // This is not a valid stream? + panic(fmt.Errorf("unknown header: %d", hdr)) + } +} + +// saveTypeSpec saves TypeSpec values. +func saveTypeSpec(w Writer, t TypeSpec) { + switch x := t.(type) { + case TypeID: + typeSpecTypeID.save(w) + Uint(x).save(w) + case *TypeSpecPointer: + typeSpecPointer.save(w) + saveTypeSpec(w, x.Type) + case *TypeSpecArray: + typeSpecArray.save(w) + x.Count.save(w) + saveTypeSpec(w, x.Type) + case *TypeSpecSlice: + typeSpecSlice.save(w) + saveTypeSpec(w, x.Type) + case *TypeSpecMap: + typeSpecMap.save(w) + saveTypeSpec(w, x.Key) + saveTypeSpec(w, x.Value) + case TypeSpecNil: + typeSpecNil.save(w) + default: + // This should not happen? + panic(fmt.Errorf("unknown type %T", t)) + } +} + +// Interface is an interface value. +type Interface struct { + Type TypeSpec + Value Object +} + +// loadInterface loads an object of type Interface. +func loadInterface(r Reader) Interface { + return Interface{ + Type: loadTypeSpec(r), + Value: Load(r), + } +} + +// save implements Object.save. +func (i *Interface) save(w Writer) { + saveTypeSpec(w, i.Type) + Save(w, i.Value) +} + +// load implements Object.load. +func (*Interface) load(r Reader) Object { + i := loadInterface(r) + return &i +} + +// Type is type information. +type Type struct { + Name string + Fields []string +} + +// loadType loads an object of type Type. +func loadType(r Reader) Type { + name := string(loadString(r)) + l := loadUint(r) + fields := make([]string, l) + for i := 0; i < int(l); i++ { + fields[i] = string(loadString(r)) + } + return Type{ + Name: name, + Fields: fields, + } +} + +// save implements Object.save. +func (t *Type) save(w Writer) { + s := String(t.Name) + s.save(w) + l := Uint(len(t.Fields)) + l.save(w) + for i := 0; i < int(l); i++ { + s := String(t.Fields[i]) + s.save(w) + } +} + +// load implements Object.load. +func (*Type) load(r Reader) Object { + t := loadType(r) + return &t +} + +// multipleObjects is a special type for serializing multiple objects. +type multipleObjects []Object + +// loadMultipleObjects loads a series of objects. +func loadMultipleObjects(r Reader) multipleObjects { + l := loadUint(r) + m := make(multipleObjects, l) + for i := 0; i < int(l); i++ { + m[i] = Load(r) + } + return m +} + +// save implements Object.save. +func (m *multipleObjects) save(w Writer) { + l := Uint(len(*m)) + l.save(w) + for i := 0; i < int(l); i++ { + Save(w, (*m)[i]) + } +} + +// load implements Object.load. +func (*multipleObjects) load(r Reader) Object { + m := loadMultipleObjects(r) + return &m +} + +// noObjects represents no objects. +type noObjects struct{} + +// loadNoObjects loads a sentinel. +func loadNoObjects(r Reader) noObjects { return noObjects{} } + +// save implements Object.save. +func (noObjects) save(w Writer) {} + +// load implements Object.load. +func (noObjects) load(r Reader) Object { return loadNoObjects(r) } + +// Struct is a basic composite value. +type Struct struct { + TypeID TypeID + fields Object // Optionally noObjects or *multipleObjects. +} + +// Field returns a pointer to the given field slot. +// +// This must be called after Alloc. +func (s *Struct) Field(i int) *Object { + if fields, ok := s.fields.(*multipleObjects); ok { + return &((*fields)[i]) + } + if _, ok := s.fields.(noObjects); ok { + // Alloc may be optionally called; can't call twice. + panic("Field called inappropriately, wrong Alloc?") + } + return &s.fields +} + +// Alloc allocates the given number of fields. +// +// This must be called before Add and Save. +// +// Precondition: slots must be positive. +func (s *Struct) Alloc(slots int) { + switch { + case slots == 0: + s.fields = noObjects{} + case slots == 1: + // Leave it alone. + case slots > 1: + fields := make(multipleObjects, slots) + s.fields = &fields + default: + // Violates precondition. + panic(fmt.Sprintf("Alloc called with negative slots %d?", slots)) + } +} + +// Fields returns the number of fields. +func (s *Struct) Fields() int { + switch x := s.fields.(type) { + case *multipleObjects: + return len(*x) + case noObjects: + return 0 + default: + return 1 + } +} + +// loadStruct loads an object of type Struct. +func loadStruct(r Reader) Struct { + return Struct{ + TypeID: TypeID(loadUint(r)), + fields: Load(r), + } +} + +// save implements Object.save. +// +// Precondition: Alloc must have been called, and the fields all filled in +// appropriately. See Alloc and Add for more details. +func (s *Struct) save(w Writer) { + Uint(s.TypeID).save(w) + Save(w, s.fields) +} + +// load implements Object.load. +func (*Struct) load(r Reader) Object { + s := loadStruct(r) + return &s +} + +// Object types. +// +// N.B. Be careful about changing the order or introducing new elements in the +// middle here. This is part of the wire format and shouldn't change. +const ( + typeBool Uint = iota + typeInt + typeUint + typeFloat32 + typeFloat64 + typeNil + typeRef + typeString + typeSlice + typeArray + typeMap + typeStruct + typeNoObjects + typeMultipleObjects + typeInterface + typeComplex64 + typeComplex128 + typeType +) + +// Save saves the given object. +// +// +checkescape all +// +// N.B. This function will panic on error. +func Save(w Writer, obj Object) { + switch x := obj.(type) { + case Bool: + typeBool.save(w) + x.save(w) + case Int: + typeInt.save(w) + x.save(w) + case Uint: + typeUint.save(w) + x.save(w) + case Float32: + typeFloat32.save(w) + x.save(w) + case Float64: + typeFloat64.save(w) + x.save(w) + case Nil: + typeNil.save(w) + x.save(w) + case *Ref: + typeRef.save(w) + x.save(w) + case *String: + typeString.save(w) + x.save(w) + case *Slice: + typeSlice.save(w) + x.save(w) + case *Array: + typeArray.save(w) + x.save(w) + case *Map: + typeMap.save(w) + x.save(w) + case *Struct: + typeStruct.save(w) + x.save(w) + case noObjects: + typeNoObjects.save(w) + x.save(w) + case *multipleObjects: + typeMultipleObjects.save(w) + x.save(w) + case *Interface: + typeInterface.save(w) + x.save(w) + case *Type: + typeType.save(w) + x.save(w) + case *Complex64: + typeComplex64.save(w) + x.save(w) + case *Complex128: + typeComplex128.save(w) + x.save(w) + default: + panic(fmt.Errorf("unknown type: %#v", obj)) + } +} + +// Load loads a new object. +// +// +checkescape all +// +// N.B. This function will panic on error. +func Load(r Reader) Object { + switch hdr := loadUint(r); hdr { + case typeBool: + return loadBool(r) + case typeInt: + return loadInt(r) + case typeUint: + return loadUint(r) + case typeFloat32: + return loadFloat32(r) + case typeFloat64: + return loadFloat64(r) + case typeNil: + return loadNil(r) + case typeRef: + return ((*Ref)(nil)).load(r) // Escapes. + case typeString: + return ((*String)(nil)).load(r) // Escapes. + case typeSlice: + return ((*Slice)(nil)).load(r) // Escapes. + case typeArray: + return ((*Array)(nil)).load(r) // Escapes. + case typeMap: + return ((*Map)(nil)).load(r) // Escapes. + case typeStruct: + return ((*Struct)(nil)).load(r) // Escapes. + case typeNoObjects: // Special for struct. + return loadNoObjects(r) + case typeMultipleObjects: // Special for struct. + return ((*multipleObjects)(nil)).load(r) // Escapes. + case typeInterface: + return ((*Interface)(nil)).load(r) // Escapes. + case typeComplex64: + return ((*Complex64)(nil)).load(r) // Escapes. + case typeComplex128: + return ((*Complex128)(nil)).load(r) // Escapes. + case typeType: + return ((*Type)(nil)).load(r) // Escapes. + default: + // This is not a valid stream? + panic(fmt.Errorf("unknown header: %d", hdr)) + } +} + +// LoadUint loads a single unsigned integer. +// +// N.B. This function will panic on error. +func LoadUint(r Reader) uint64 { + return uint64(loadUint(r)) +} + +// SaveUint saves a single unsigned integer. +// +// N.B. This function will panic on error. +func SaveUint(w Writer, v uint64) { + Uint(v).save(w) +} diff --git a/pkg/tcpip/buffer/buffer_state_autogen.go b/pkg/tcpip/buffer/buffer_state_autogen.go index 954487771..67db6f4d9 100644 --- a/pkg/tcpip/buffer/buffer_state_autogen.go +++ b/pkg/tcpip/buffer/buffer_state_autogen.go @@ -6,19 +6,32 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *VectorisedView) StateTypeName() string { + return "pkg/tcpip/buffer.VectorisedView" +} + +func (x *VectorisedView) StateFields() []string { + return []string{ + "views", + "size", + } +} + func (x *VectorisedView) beforeSave() {} -func (x *VectorisedView) save(m state.Map) { + +func (x *VectorisedView) StateSave(m state.Sink) { x.beforeSave() - m.Save("views", &x.views) - m.Save("size", &x.size) + m.Save(0, &x.views) + m.Save(1, &x.size) } func (x *VectorisedView) afterLoad() {} -func (x *VectorisedView) load(m state.Map) { - m.Load("views", &x.views) - m.Load("size", &x.size) + +func (x *VectorisedView) StateLoad(m state.Source) { + m.Load(0, &x.views) + m.Load(1, &x.size) } func init() { - state.Register("pkg/tcpip/buffer.VectorisedView", (*VectorisedView)(nil), state.Fns{Save: (*VectorisedView).save, Load: (*VectorisedView).load}) + state.Register((*VectorisedView)(nil)) } diff --git a/pkg/tcpip/header/header_state_autogen.go b/pkg/tcpip/header/header_state_autogen.go index 015d7e12a..7efd361fb 100644 --- a/pkg/tcpip/header/header_state_autogen.go +++ b/pkg/tcpip/header/header_state_autogen.go @@ -6,37 +6,65 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *SACKBlock) StateTypeName() string { + return "pkg/tcpip/header.SACKBlock" +} + +func (x *SACKBlock) StateFields() []string { + return []string{ + "Start", + "End", + } +} + func (x *SACKBlock) beforeSave() {} -func (x *SACKBlock) save(m state.Map) { + +func (x *SACKBlock) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) + m.Save(0, &x.Start) + m.Save(1, &x.End) } func (x *SACKBlock) afterLoad() {} -func (x *SACKBlock) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) + +func (x *SACKBlock) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) +} + +func (x *TCPOptions) StateTypeName() string { + return "pkg/tcpip/header.TCPOptions" +} + +func (x *TCPOptions) StateFields() []string { + return []string{ + "TS", + "TSVal", + "TSEcr", + "SACKBlocks", + } } func (x *TCPOptions) beforeSave() {} -func (x *TCPOptions) save(m state.Map) { + +func (x *TCPOptions) StateSave(m state.Sink) { x.beforeSave() - m.Save("TS", &x.TS) - m.Save("TSVal", &x.TSVal) - m.Save("TSEcr", &x.TSEcr) - m.Save("SACKBlocks", &x.SACKBlocks) + m.Save(0, &x.TS) + m.Save(1, &x.TSVal) + m.Save(2, &x.TSEcr) + m.Save(3, &x.SACKBlocks) } func (x *TCPOptions) afterLoad() {} -func (x *TCPOptions) load(m state.Map) { - m.Load("TS", &x.TS) - m.Load("TSVal", &x.TSVal) - m.Load("TSEcr", &x.TSEcr) - m.Load("SACKBlocks", &x.SACKBlocks) + +func (x *TCPOptions) StateLoad(m state.Source) { + m.Load(0, &x.TS) + m.Load(1, &x.TSVal) + m.Load(2, &x.TSEcr) + m.Load(3, &x.SACKBlocks) } func init() { - state.Register("pkg/tcpip/header.SACKBlock", (*SACKBlock)(nil), state.Fns{Save: (*SACKBlock).save, Load: (*SACKBlock).load}) - state.Register("pkg/tcpip/header.TCPOptions", (*TCPOptions)(nil), state.Fns{Save: (*TCPOptions).save, Load: (*TCPOptions).load}) + state.Register((*SACKBlock)(nil)) + state.Register((*TCPOptions)(nil)) } diff --git a/pkg/tcpip/link/channel/channel_state_autogen.go b/pkg/tcpip/link/channel/channel_state_autogen.go index ce52482a2..d00c11cb2 100644 --- a/pkg/tcpip/link/channel/channel_state_autogen.go +++ b/pkg/tcpip/link/channel/channel_state_autogen.go @@ -6,17 +6,29 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *NotificationHandle) StateTypeName() string { + return "pkg/tcpip/link/channel.NotificationHandle" +} + +func (x *NotificationHandle) StateFields() []string { + return []string{ + "n", + } +} + func (x *NotificationHandle) beforeSave() {} -func (x *NotificationHandle) save(m state.Map) { + +func (x *NotificationHandle) StateSave(m state.Sink) { x.beforeSave() - m.Save("n", &x.n) + m.Save(0, &x.n) } func (x *NotificationHandle) afterLoad() {} -func (x *NotificationHandle) load(m state.Map) { - m.Load("n", &x.n) + +func (x *NotificationHandle) StateLoad(m state.Source) { + m.Load(0, &x.n) } func init() { - state.Register("pkg/tcpip/link/channel.NotificationHandle", (*NotificationHandle)(nil), state.Fns{Save: (*NotificationHandle).save, Load: (*NotificationHandle).load}) + state.Register((*NotificationHandle)(nil)) } diff --git a/pkg/tcpip/link/tun/tun_state_autogen.go b/pkg/tcpip/link/tun/tun_state_autogen.go index 4b70647af..7f75aef19 100644 --- a/pkg/tcpip/link/tun/tun_state_autogen.go +++ b/pkg/tcpip/link/tun/tun_state_autogen.go @@ -6,22 +6,36 @@ import ( "gvisor.dev/gvisor/pkg/state" ) -func (x *Device) save(m state.Map) { +func (x *Device) StateTypeName() string { + return "pkg/tcpip/link/tun.Device" +} + +func (x *Device) StateFields() []string { + return []string{ + "Queue", + "endpoint", + "notifyHandle", + "flags", + } +} + +func (x *Device) StateSave(m state.Sink) { x.beforeSave() - m.Save("Queue", &x.Queue) - m.Save("endpoint", &x.endpoint) - m.Save("notifyHandle", &x.notifyHandle) - m.Save("flags", &x.flags) + m.Save(0, &x.Queue) + m.Save(1, &x.endpoint) + m.Save(2, &x.notifyHandle) + m.Save(3, &x.flags) } func (x *Device) afterLoad() {} -func (x *Device) load(m state.Map) { - m.Load("Queue", &x.Queue) - m.Load("endpoint", &x.endpoint) - m.Load("notifyHandle", &x.notifyHandle) - m.Load("flags", &x.flags) + +func (x *Device) StateLoad(m state.Source) { + m.Load(0, &x.Queue) + m.Load(1, &x.endpoint) + m.Load(2, &x.notifyHandle) + m.Load(3, &x.flags) } func init() { - state.Register("pkg/tcpip/link/tun.Device", (*Device)(nil), state.Fns{Save: (*Device).save, Load: (*Device).load}) + state.Register((*Device)(nil)) } diff --git a/pkg/tcpip/network/fragmentation/fragmentation_state_autogen.go b/pkg/tcpip/network/fragmentation/fragmentation_state_autogen.go index cbaecdaa7..780ddfdc3 100644 --- a/pkg/tcpip/network/fragmentation/fragmentation_state_autogen.go +++ b/pkg/tcpip/network/fragmentation/fragmentation_state_autogen.go @@ -6,33 +6,59 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *reassemblerList) StateTypeName() string { + return "pkg/tcpip/network/fragmentation.reassemblerList" +} + +func (x *reassemblerList) StateFields() []string { + return []string{ + "head", + "tail", + } +} + func (x *reassemblerList) beforeSave() {} -func (x *reassemblerList) save(m state.Map) { + +func (x *reassemblerList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *reassemblerList) afterLoad() {} -func (x *reassemblerList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *reassemblerList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *reassemblerEntry) StateTypeName() string { + return "pkg/tcpip/network/fragmentation.reassemblerEntry" +} + +func (x *reassemblerEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *reassemblerEntry) beforeSave() {} -func (x *reassemblerEntry) save(m state.Map) { + +func (x *reassemblerEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *reassemblerEntry) afterLoad() {} -func (x *reassemblerEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *reassemblerEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) } func init() { - state.Register("pkg/tcpip/network/fragmentation.reassemblerList", (*reassemblerList)(nil), state.Fns{Save: (*reassemblerList).save, Load: (*reassemblerList).load}) - state.Register("pkg/tcpip/network/fragmentation.reassemblerEntry", (*reassemblerEntry)(nil), state.Fns{Save: (*reassemblerEntry).save, Load: (*reassemblerEntry).load}) + state.Register((*reassemblerList)(nil)) + state.Register((*reassemblerEntry)(nil)) } diff --git a/pkg/tcpip/network/fragmentation/reassembler_list.go b/pkg/tcpip/network/fragmentation/reassembler_list.go index b5d40bd25..bb5bd75c4 100644 --- a/pkg/tcpip/network/fragmentation/reassembler_list.go +++ b/pkg/tcpip/network/fragmentation/reassembler_list.go @@ -56,7 +56,7 @@ func (l *reassemblerList) Back() *reassembler { // // NOTE: This is an O(n) operation. func (l *reassemblerList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (reassemblerElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *reassemblerList) Remove(e *reassembler) { if prev != nil { reassemblerElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { reassemblerElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/tcpip/ports/ports_state_autogen.go b/pkg/tcpip/ports/ports_state_autogen.go index 40d094060..54db0b8f9 100644 --- a/pkg/tcpip/ports/ports_state_autogen.go +++ b/pkg/tcpip/ports/ports_state_autogen.go @@ -6,21 +6,35 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *Flags) StateTypeName() string { + return "pkg/tcpip/ports.Flags" +} + +func (x *Flags) StateFields() []string { + return []string{ + "MostRecent", + "LoadBalanced", + "TupleOnly", + } +} + func (x *Flags) beforeSave() {} -func (x *Flags) save(m state.Map) { + +func (x *Flags) StateSave(m state.Sink) { x.beforeSave() - m.Save("MostRecent", &x.MostRecent) - m.Save("LoadBalanced", &x.LoadBalanced) - m.Save("TupleOnly", &x.TupleOnly) + m.Save(0, &x.MostRecent) + m.Save(1, &x.LoadBalanced) + m.Save(2, &x.TupleOnly) } func (x *Flags) afterLoad() {} -func (x *Flags) load(m state.Map) { - m.Load("MostRecent", &x.MostRecent) - m.Load("LoadBalanced", &x.LoadBalanced) - m.Load("TupleOnly", &x.TupleOnly) + +func (x *Flags) StateLoad(m state.Source) { + m.Load(0, &x.MostRecent) + m.Load(1, &x.LoadBalanced) + m.Load(2, &x.TupleOnly) } func init() { - state.Register("pkg/tcpip/ports.Flags", (*Flags)(nil), state.Fns{Save: (*Flags).save, Load: (*Flags).load}) + state.Register((*Flags)(nil)) } diff --git a/pkg/tcpip/stack/linkaddrentry_list.go b/pkg/tcpip/stack/linkaddrentry_list.go index 43022f9b3..1250b89f8 100644 --- a/pkg/tcpip/stack/linkaddrentry_list.go +++ b/pkg/tcpip/stack/linkaddrentry_list.go @@ -56,7 +56,7 @@ func (l *linkAddrEntryList) Back() *linkAddrEntry { // // NOTE: This is an O(n) operation. func (l *linkAddrEntryList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (linkAddrEntryElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *linkAddrEntryList) Remove(e *linkAddrEntry) { if prev != nil { linkAddrEntryElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { linkAddrEntryElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/tcpip/stack/packet_buffer_list.go b/pkg/tcpip/stack/packet_buffer_list.go index 460c74c5a..27f15cb15 100644 --- a/pkg/tcpip/stack/packet_buffer_list.go +++ b/pkg/tcpip/stack/packet_buffer_list.go @@ -56,7 +56,7 @@ func (l *PacketBufferList) Back() *PacketBuffer { // // NOTE: This is an O(n) operation. func (l *PacketBufferList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (PacketBufferElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *PacketBufferList) Remove(e *PacketBuffer) { if prev != nil { PacketBufferElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { PacketBufferElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/tcpip/stack/stack_state_autogen.go b/pkg/tcpip/stack/stack_state_autogen.go index 32d310c2f..6efa9a773 100644 --- a/pkg/tcpip/stack/stack_state_autogen.go +++ b/pkg/tcpip/stack/stack_state_autogen.go @@ -6,152 +6,269 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *linkAddrEntryList) StateTypeName() string { + return "pkg/tcpip/stack.linkAddrEntryList" +} + +func (x *linkAddrEntryList) StateFields() []string { + return []string{ + "head", + "tail", + } +} + func (x *linkAddrEntryList) beforeSave() {} -func (x *linkAddrEntryList) save(m state.Map) { + +func (x *linkAddrEntryList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *linkAddrEntryList) afterLoad() {} -func (x *linkAddrEntryList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *linkAddrEntryList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *linkAddrEntryEntry) StateTypeName() string { + return "pkg/tcpip/stack.linkAddrEntryEntry" +} + +func (x *linkAddrEntryEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *linkAddrEntryEntry) beforeSave() {} -func (x *linkAddrEntryEntry) save(m state.Map) { + +func (x *linkAddrEntryEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *linkAddrEntryEntry) afterLoad() {} -func (x *linkAddrEntryEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *linkAddrEntryEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) +} + +func (x *PacketBufferList) StateTypeName() string { + return "pkg/tcpip/stack.PacketBufferList" +} + +func (x *PacketBufferList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *PacketBufferList) beforeSave() {} -func (x *PacketBufferList) save(m state.Map) { + +func (x *PacketBufferList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *PacketBufferList) afterLoad() {} -func (x *PacketBufferList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *PacketBufferList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *PacketBufferEntry) StateTypeName() string { + return "pkg/tcpip/stack.PacketBufferEntry" +} + +func (x *PacketBufferEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *PacketBufferEntry) beforeSave() {} -func (x *PacketBufferEntry) save(m state.Map) { + +func (x *PacketBufferEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *PacketBufferEntry) afterLoad() {} -func (x *PacketBufferEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *PacketBufferEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) +} + +func (x *TransportEndpointID) StateTypeName() string { + return "pkg/tcpip/stack.TransportEndpointID" +} + +func (x *TransportEndpointID) StateFields() []string { + return []string{ + "LocalPort", + "LocalAddress", + "RemotePort", + "RemoteAddress", + } } func (x *TransportEndpointID) beforeSave() {} -func (x *TransportEndpointID) save(m state.Map) { + +func (x *TransportEndpointID) StateSave(m state.Sink) { x.beforeSave() - m.Save("LocalPort", &x.LocalPort) - m.Save("LocalAddress", &x.LocalAddress) - m.Save("RemotePort", &x.RemotePort) - m.Save("RemoteAddress", &x.RemoteAddress) + m.Save(0, &x.LocalPort) + m.Save(1, &x.LocalAddress) + m.Save(2, &x.RemotePort) + m.Save(3, &x.RemoteAddress) } func (x *TransportEndpointID) afterLoad() {} -func (x *TransportEndpointID) load(m state.Map) { - m.Load("LocalPort", &x.LocalPort) - m.Load("LocalAddress", &x.LocalAddress) - m.Load("RemotePort", &x.RemotePort) - m.Load("RemoteAddress", &x.RemoteAddress) + +func (x *TransportEndpointID) StateLoad(m state.Source) { + m.Load(0, &x.LocalPort) + m.Load(1, &x.LocalAddress) + m.Load(2, &x.RemotePort) + m.Load(3, &x.RemoteAddress) } -func (x *GSOType) save(m state.Map) { - m.SaveValue("", (int)(*x)) +func (x *GSOType) StateTypeName() string { + return "pkg/tcpip/stack.GSOType" } -func (x *GSOType) load(m state.Map) { - m.LoadValue("", new(int), func(y interface{}) { *x = (GSOType)(y.(int)) }) +func (x *GSOType) StateFields() []string { + return nil +} + +func (x *GSO) StateTypeName() string { + return "pkg/tcpip/stack.GSO" +} + +func (x *GSO) StateFields() []string { + return []string{ + "Type", + "NeedsCsum", + "CsumOffset", + "MSS", + "L3HdrLen", + "MaxSize", + } } func (x *GSO) beforeSave() {} -func (x *GSO) save(m state.Map) { + +func (x *GSO) StateSave(m state.Sink) { x.beforeSave() - m.Save("Type", &x.Type) - m.Save("NeedsCsum", &x.NeedsCsum) - m.Save("CsumOffset", &x.CsumOffset) - m.Save("MSS", &x.MSS) - m.Save("L3HdrLen", &x.L3HdrLen) - m.Save("MaxSize", &x.MaxSize) + m.Save(0, &x.Type) + m.Save(1, &x.NeedsCsum) + m.Save(2, &x.CsumOffset) + m.Save(3, &x.MSS) + m.Save(4, &x.L3HdrLen) + m.Save(5, &x.MaxSize) } func (x *GSO) afterLoad() {} -func (x *GSO) load(m state.Map) { - m.Load("Type", &x.Type) - m.Load("NeedsCsum", &x.NeedsCsum) - m.Load("CsumOffset", &x.CsumOffset) - m.Load("MSS", &x.MSS) - m.Load("L3HdrLen", &x.L3HdrLen) - m.Load("MaxSize", &x.MaxSize) + +func (x *GSO) StateLoad(m state.Source) { + m.Load(0, &x.Type) + m.Load(1, &x.NeedsCsum) + m.Load(2, &x.CsumOffset) + m.Load(3, &x.MSS) + m.Load(4, &x.L3HdrLen) + m.Load(5, &x.MaxSize) +} + +func (x *TransportEndpointInfo) StateTypeName() string { + return "pkg/tcpip/stack.TransportEndpointInfo" +} + +func (x *TransportEndpointInfo) StateFields() []string { + return []string{ + "NetProto", + "TransProto", + "ID", + "BindNICID", + "BindAddr", + "RegisterNICID", + } } func (x *TransportEndpointInfo) beforeSave() {} -func (x *TransportEndpointInfo) save(m state.Map) { + +func (x *TransportEndpointInfo) StateSave(m state.Sink) { x.beforeSave() - m.Save("NetProto", &x.NetProto) - m.Save("TransProto", &x.TransProto) - m.Save("ID", &x.ID) - m.Save("BindNICID", &x.BindNICID) - m.Save("BindAddr", &x.BindAddr) - m.Save("RegisterNICID", &x.RegisterNICID) + m.Save(0, &x.NetProto) + m.Save(1, &x.TransProto) + m.Save(2, &x.ID) + m.Save(3, &x.BindNICID) + m.Save(4, &x.BindAddr) + m.Save(5, &x.RegisterNICID) } func (x *TransportEndpointInfo) afterLoad() {} -func (x *TransportEndpointInfo) load(m state.Map) { - m.Load("NetProto", &x.NetProto) - m.Load("TransProto", &x.TransProto) - m.Load("ID", &x.ID) - m.Load("BindNICID", &x.BindNICID) - m.Load("BindAddr", &x.BindAddr) - m.Load("RegisterNICID", &x.RegisterNICID) + +func (x *TransportEndpointInfo) StateLoad(m state.Source) { + m.Load(0, &x.NetProto) + m.Load(1, &x.TransProto) + m.Load(2, &x.ID) + m.Load(3, &x.BindNICID) + m.Load(4, &x.BindAddr) + m.Load(5, &x.RegisterNICID) +} + +func (x *multiPortEndpoint) StateTypeName() string { + return "pkg/tcpip/stack.multiPortEndpoint" +} + +func (x *multiPortEndpoint) StateFields() []string { + return []string{ + "demux", + "netProto", + "transProto", + "endpoints", + "flags", + } } func (x *multiPortEndpoint) beforeSave() {} -func (x *multiPortEndpoint) save(m state.Map) { + +func (x *multiPortEndpoint) StateSave(m state.Sink) { x.beforeSave() - m.Save("demux", &x.demux) - m.Save("netProto", &x.netProto) - m.Save("transProto", &x.transProto) - m.Save("endpoints", &x.endpoints) - m.Save("flags", &x.flags) + m.Save(0, &x.demux) + m.Save(1, &x.netProto) + m.Save(2, &x.transProto) + m.Save(3, &x.endpoints) + m.Save(4, &x.flags) } func (x *multiPortEndpoint) afterLoad() {} -func (x *multiPortEndpoint) load(m state.Map) { - m.Load("demux", &x.demux) - m.Load("netProto", &x.netProto) - m.Load("transProto", &x.transProto) - m.Load("endpoints", &x.endpoints) - m.Load("flags", &x.flags) + +func (x *multiPortEndpoint) StateLoad(m state.Source) { + m.Load(0, &x.demux) + m.Load(1, &x.netProto) + m.Load(2, &x.transProto) + m.Load(3, &x.endpoints) + m.Load(4, &x.flags) } func init() { - state.Register("pkg/tcpip/stack.linkAddrEntryList", (*linkAddrEntryList)(nil), state.Fns{Save: (*linkAddrEntryList).save, Load: (*linkAddrEntryList).load}) - state.Register("pkg/tcpip/stack.linkAddrEntryEntry", (*linkAddrEntryEntry)(nil), state.Fns{Save: (*linkAddrEntryEntry).save, Load: (*linkAddrEntryEntry).load}) - state.Register("pkg/tcpip/stack.PacketBufferList", (*PacketBufferList)(nil), state.Fns{Save: (*PacketBufferList).save, Load: (*PacketBufferList).load}) - state.Register("pkg/tcpip/stack.PacketBufferEntry", (*PacketBufferEntry)(nil), state.Fns{Save: (*PacketBufferEntry).save, Load: (*PacketBufferEntry).load}) - state.Register("pkg/tcpip/stack.TransportEndpointID", (*TransportEndpointID)(nil), state.Fns{Save: (*TransportEndpointID).save, Load: (*TransportEndpointID).load}) - state.Register("pkg/tcpip/stack.GSOType", (*GSOType)(nil), state.Fns{Save: (*GSOType).save, Load: (*GSOType).load}) - state.Register("pkg/tcpip/stack.GSO", (*GSO)(nil), state.Fns{Save: (*GSO).save, Load: (*GSO).load}) - state.Register("pkg/tcpip/stack.TransportEndpointInfo", (*TransportEndpointInfo)(nil), state.Fns{Save: (*TransportEndpointInfo).save, Load: (*TransportEndpointInfo).load}) - state.Register("pkg/tcpip/stack.multiPortEndpoint", (*multiPortEndpoint)(nil), state.Fns{Save: (*multiPortEndpoint).save, Load: (*multiPortEndpoint).load}) + state.Register((*linkAddrEntryList)(nil)) + state.Register((*linkAddrEntryEntry)(nil)) + state.Register((*PacketBufferList)(nil)) + state.Register((*PacketBufferEntry)(nil)) + state.Register((*TransportEndpointID)(nil)) + state.Register((*GSOType)(nil)) + state.Register((*GSO)(nil)) + state.Register((*TransportEndpointInfo)(nil)) + state.Register((*multiPortEndpoint)(nil)) } diff --git a/pkg/tcpip/tcpip_state_autogen.go b/pkg/tcpip/tcpip_state_autogen.go index 8ea900688..28d5ae82b 100644 --- a/pkg/tcpip/tcpip_state_autogen.go +++ b/pkg/tcpip/tcpip_state_autogen.go @@ -6,67 +6,116 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *FullAddress) StateTypeName() string { + return "pkg/tcpip.FullAddress" +} + +func (x *FullAddress) StateFields() []string { + return []string{ + "NIC", + "Addr", + "Port", + } +} + func (x *FullAddress) beforeSave() {} -func (x *FullAddress) save(m state.Map) { + +func (x *FullAddress) StateSave(m state.Sink) { x.beforeSave() - m.Save("NIC", &x.NIC) - m.Save("Addr", &x.Addr) - m.Save("Port", &x.Port) + m.Save(0, &x.NIC) + m.Save(1, &x.Addr) + m.Save(2, &x.Port) } func (x *FullAddress) afterLoad() {} -func (x *FullAddress) load(m state.Map) { - m.Load("NIC", &x.NIC) - m.Load("Addr", &x.Addr) - m.Load("Port", &x.Port) + +func (x *FullAddress) StateLoad(m state.Source) { + m.Load(0, &x.NIC) + m.Load(1, &x.Addr) + m.Load(2, &x.Port) +} + +func (x *ControlMessages) StateTypeName() string { + return "pkg/tcpip.ControlMessages" +} + +func (x *ControlMessages) StateFields() []string { + return []string{ + "HasTimestamp", + "Timestamp", + "HasInq", + "Inq", + "HasTOS", + "TOS", + "HasTClass", + "TClass", + "HasIPPacketInfo", + "PacketInfo", + } } func (x *ControlMessages) beforeSave() {} -func (x *ControlMessages) save(m state.Map) { + +func (x *ControlMessages) StateSave(m state.Sink) { x.beforeSave() - m.Save("HasTimestamp", &x.HasTimestamp) - m.Save("Timestamp", &x.Timestamp) - m.Save("HasInq", &x.HasInq) - m.Save("Inq", &x.Inq) - m.Save("HasTOS", &x.HasTOS) - m.Save("TOS", &x.TOS) - m.Save("HasTClass", &x.HasTClass) - m.Save("TClass", &x.TClass) - m.Save("HasIPPacketInfo", &x.HasIPPacketInfo) - m.Save("PacketInfo", &x.PacketInfo) + m.Save(0, &x.HasTimestamp) + m.Save(1, &x.Timestamp) + m.Save(2, &x.HasInq) + m.Save(3, &x.Inq) + m.Save(4, &x.HasTOS) + m.Save(5, &x.TOS) + m.Save(6, &x.HasTClass) + m.Save(7, &x.TClass) + m.Save(8, &x.HasIPPacketInfo) + m.Save(9, &x.PacketInfo) } func (x *ControlMessages) afterLoad() {} -func (x *ControlMessages) load(m state.Map) { - m.Load("HasTimestamp", &x.HasTimestamp) - m.Load("Timestamp", &x.Timestamp) - m.Load("HasInq", &x.HasInq) - m.Load("Inq", &x.Inq) - m.Load("HasTOS", &x.HasTOS) - m.Load("TOS", &x.TOS) - m.Load("HasTClass", &x.HasTClass) - m.Load("TClass", &x.TClass) - m.Load("HasIPPacketInfo", &x.HasIPPacketInfo) - m.Load("PacketInfo", &x.PacketInfo) + +func (x *ControlMessages) StateLoad(m state.Source) { + m.Load(0, &x.HasTimestamp) + m.Load(1, &x.Timestamp) + m.Load(2, &x.HasInq) + m.Load(3, &x.Inq) + m.Load(4, &x.HasTOS) + m.Load(5, &x.TOS) + m.Load(6, &x.HasTClass) + m.Load(7, &x.TClass) + m.Load(8, &x.HasIPPacketInfo) + m.Load(9, &x.PacketInfo) +} + +func (x *IPPacketInfo) StateTypeName() string { + return "pkg/tcpip.IPPacketInfo" +} + +func (x *IPPacketInfo) StateFields() []string { + return []string{ + "NIC", + "LocalAddr", + "DestinationAddr", + } } func (x *IPPacketInfo) beforeSave() {} -func (x *IPPacketInfo) save(m state.Map) { + +func (x *IPPacketInfo) StateSave(m state.Sink) { x.beforeSave() - m.Save("NIC", &x.NIC) - m.Save("LocalAddr", &x.LocalAddr) - m.Save("DestinationAddr", &x.DestinationAddr) + m.Save(0, &x.NIC) + m.Save(1, &x.LocalAddr) + m.Save(2, &x.DestinationAddr) } func (x *IPPacketInfo) afterLoad() {} -func (x *IPPacketInfo) load(m state.Map) { - m.Load("NIC", &x.NIC) - m.Load("LocalAddr", &x.LocalAddr) - m.Load("DestinationAddr", &x.DestinationAddr) + +func (x *IPPacketInfo) StateLoad(m state.Source) { + m.Load(0, &x.NIC) + m.Load(1, &x.LocalAddr) + m.Load(2, &x.DestinationAddr) } func init() { - state.Register("pkg/tcpip.FullAddress", (*FullAddress)(nil), state.Fns{Save: (*FullAddress).save, Load: (*FullAddress).load}) - state.Register("pkg/tcpip.ControlMessages", (*ControlMessages)(nil), state.Fns{Save: (*ControlMessages).save, Load: (*ControlMessages).load}) - state.Register("pkg/tcpip.IPPacketInfo", (*IPPacketInfo)(nil), state.Fns{Save: (*IPPacketInfo).save, Load: (*IPPacketInfo).load}) + state.Register((*FullAddress)(nil)) + state.Register((*ControlMessages)(nil)) + state.Register((*IPPacketInfo)(nil)) } diff --git a/pkg/tcpip/tcpip_unsafe_state_autogen.go b/pkg/tcpip/tcpip_unsafe_state_autogen.go index 9423c098b..ae5ab873a 100644 --- a/pkg/tcpip/tcpip_unsafe_state_autogen.go +++ b/pkg/tcpip/tcpip_unsafe_state_autogen.go @@ -9,15 +9,25 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *StdClock) StateTypeName() string { + return "pkg/tcpip.StdClock" +} + +func (x *StdClock) StateFields() []string { + return []string{} +} + func (x *StdClock) beforeSave() {} -func (x *StdClock) save(m state.Map) { + +func (x *StdClock) StateSave(m state.Sink) { x.beforeSave() } func (x *StdClock) afterLoad() {} -func (x *StdClock) load(m state.Map) { + +func (x *StdClock) StateLoad(m state.Source) { } func init() { - state.Register("pkg/tcpip.StdClock", (*StdClock)(nil), state.Fns{Save: (*StdClock).save, Load: (*StdClock).load}) + state.Register((*StdClock)(nil)) } diff --git a/pkg/tcpip/transport/icmp/icmp_packet_list.go b/pkg/tcpip/transport/icmp/icmp_packet_list.go index 42d63f976..f69543bda 100644 --- a/pkg/tcpip/transport/icmp/icmp_packet_list.go +++ b/pkg/tcpip/transport/icmp/icmp_packet_list.go @@ -56,7 +56,7 @@ func (l *icmpPacketList) Back() *icmpPacket { // // NOTE: This is an O(n) operation. func (l *icmpPacketList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (icmpPacketElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *icmpPacketList) Remove(e *icmpPacket) { if prev != nil { icmpPacketElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { icmpPacketElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/tcpip/transport/icmp/icmp_state_autogen.go b/pkg/tcpip/transport/icmp/icmp_state_autogen.go index c26460a4b..c6b278677 100644 --- a/pkg/tcpip/transport/icmp/icmp_state_autogen.go +++ b/pkg/tcpip/transport/icmp/icmp_state_autogen.go @@ -7,88 +7,151 @@ import ( "gvisor.dev/gvisor/pkg/tcpip/buffer" ) +func (x *icmpPacket) StateTypeName() string { + return "pkg/tcpip/transport/icmp.icmpPacket" +} + +func (x *icmpPacket) StateFields() []string { + return []string{ + "icmpPacketEntry", + "senderAddress", + "data", + "timestamp", + } +} + func (x *icmpPacket) beforeSave() {} -func (x *icmpPacket) save(m state.Map) { + +func (x *icmpPacket) StateSave(m state.Sink) { x.beforeSave() var data buffer.VectorisedView = x.saveData() - m.SaveValue("data", data) - m.Save("icmpPacketEntry", &x.icmpPacketEntry) - m.Save("senderAddress", &x.senderAddress) - m.Save("timestamp", &x.timestamp) + m.SaveValue(2, data) + m.Save(0, &x.icmpPacketEntry) + m.Save(1, &x.senderAddress) + m.Save(3, &x.timestamp) } func (x *icmpPacket) afterLoad() {} -func (x *icmpPacket) load(m state.Map) { - m.Load("icmpPacketEntry", &x.icmpPacketEntry) - m.Load("senderAddress", &x.senderAddress) - m.Load("timestamp", &x.timestamp) - m.LoadValue("data", new(buffer.VectorisedView), func(y interface{}) { x.loadData(y.(buffer.VectorisedView)) }) + +func (x *icmpPacket) StateLoad(m state.Source) { + m.Load(0, &x.icmpPacketEntry) + m.Load(1, &x.senderAddress) + m.Load(3, &x.timestamp) + m.LoadValue(2, new(buffer.VectorisedView), func(y interface{}) { x.loadData(y.(buffer.VectorisedView)) }) } -func (x *endpoint) save(m state.Map) { +func (x *endpoint) StateTypeName() string { + return "pkg/tcpip/transport/icmp.endpoint" +} + +func (x *endpoint) StateFields() []string { + return []string{ + "TransportEndpointInfo", + "waiterQueue", + "uniqueID", + "rcvReady", + "rcvList", + "rcvBufSizeMax", + "rcvBufSize", + "rcvClosed", + "sndBufSize", + "shutdownFlags", + "state", + "ttl", + "owner", + } +} + +func (x *endpoint) StateSave(m state.Sink) { x.beforeSave() var rcvBufSizeMax int = x.saveRcvBufSizeMax() - m.SaveValue("rcvBufSizeMax", rcvBufSizeMax) - m.Save("TransportEndpointInfo", &x.TransportEndpointInfo) - m.Save("waiterQueue", &x.waiterQueue) - m.Save("uniqueID", &x.uniqueID) - m.Save("rcvReady", &x.rcvReady) - m.Save("rcvList", &x.rcvList) - m.Save("rcvBufSize", &x.rcvBufSize) - m.Save("rcvClosed", &x.rcvClosed) - m.Save("sndBufSize", &x.sndBufSize) - m.Save("shutdownFlags", &x.shutdownFlags) - m.Save("state", &x.state) - m.Save("ttl", &x.ttl) - m.Save("owner", &x.owner) -} - -func (x *endpoint) load(m state.Map) { - m.Load("TransportEndpointInfo", &x.TransportEndpointInfo) - m.Load("waiterQueue", &x.waiterQueue) - m.Load("uniqueID", &x.uniqueID) - m.Load("rcvReady", &x.rcvReady) - m.Load("rcvList", &x.rcvList) - m.Load("rcvBufSize", &x.rcvBufSize) - m.Load("rcvClosed", &x.rcvClosed) - m.Load("sndBufSize", &x.sndBufSize) - m.Load("shutdownFlags", &x.shutdownFlags) - m.Load("state", &x.state) - m.Load("ttl", &x.ttl) - m.Load("owner", &x.owner) - m.LoadValue("rcvBufSizeMax", new(int), func(y interface{}) { x.loadRcvBufSizeMax(y.(int)) }) + m.SaveValue(5, rcvBufSizeMax) + m.Save(0, &x.TransportEndpointInfo) + m.Save(1, &x.waiterQueue) + m.Save(2, &x.uniqueID) + m.Save(3, &x.rcvReady) + m.Save(4, &x.rcvList) + m.Save(6, &x.rcvBufSize) + m.Save(7, &x.rcvClosed) + m.Save(8, &x.sndBufSize) + m.Save(9, &x.shutdownFlags) + m.Save(10, &x.state) + m.Save(11, &x.ttl) + m.Save(12, &x.owner) +} + +func (x *endpoint) StateLoad(m state.Source) { + m.Load(0, &x.TransportEndpointInfo) + m.Load(1, &x.waiterQueue) + m.Load(2, &x.uniqueID) + m.Load(3, &x.rcvReady) + m.Load(4, &x.rcvList) + m.Load(6, &x.rcvBufSize) + m.Load(7, &x.rcvClosed) + m.Load(8, &x.sndBufSize) + m.Load(9, &x.shutdownFlags) + m.Load(10, &x.state) + m.Load(11, &x.ttl) + m.Load(12, &x.owner) + m.LoadValue(5, new(int), func(y interface{}) { x.loadRcvBufSizeMax(y.(int)) }) m.AfterLoad(x.afterLoad) } +func (x *icmpPacketList) StateTypeName() string { + return "pkg/tcpip/transport/icmp.icmpPacketList" +} + +func (x *icmpPacketList) StateFields() []string { + return []string{ + "head", + "tail", + } +} + func (x *icmpPacketList) beforeSave() {} -func (x *icmpPacketList) save(m state.Map) { + +func (x *icmpPacketList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *icmpPacketList) afterLoad() {} -func (x *icmpPacketList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *icmpPacketList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *icmpPacketEntry) StateTypeName() string { + return "pkg/tcpip/transport/icmp.icmpPacketEntry" +} + +func (x *icmpPacketEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *icmpPacketEntry) beforeSave() {} -func (x *icmpPacketEntry) save(m state.Map) { + +func (x *icmpPacketEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *icmpPacketEntry) afterLoad() {} -func (x *icmpPacketEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *icmpPacketEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) } func init() { - state.Register("pkg/tcpip/transport/icmp.icmpPacket", (*icmpPacket)(nil), state.Fns{Save: (*icmpPacket).save, Load: (*icmpPacket).load}) - state.Register("pkg/tcpip/transport/icmp.endpoint", (*endpoint)(nil), state.Fns{Save: (*endpoint).save, Load: (*endpoint).load}) - state.Register("pkg/tcpip/transport/icmp.icmpPacketList", (*icmpPacketList)(nil), state.Fns{Save: (*icmpPacketList).save, Load: (*icmpPacketList).load}) - state.Register("pkg/tcpip/transport/icmp.icmpPacketEntry", (*icmpPacketEntry)(nil), state.Fns{Save: (*icmpPacketEntry).save, Load: (*icmpPacketEntry).load}) + state.Register((*icmpPacket)(nil)) + state.Register((*endpoint)(nil)) + state.Register((*icmpPacketList)(nil)) + state.Register((*icmpPacketEntry)(nil)) } diff --git a/pkg/tcpip/transport/packet/packet_list.go b/pkg/tcpip/transport/packet/packet_list.go index 5231b066f..22a41872a 100644 --- a/pkg/tcpip/transport/packet/packet_list.go +++ b/pkg/tcpip/transport/packet/packet_list.go @@ -56,7 +56,7 @@ func (l *packetList) Back() *packet { // // NOTE: This is an O(n) operation. func (l *packetList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (packetElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *packetList) Remove(e *packet) { if prev != nil { packetElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { packetElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/tcpip/transport/packet/packet_state_autogen.go b/pkg/tcpip/transport/packet/packet_state_autogen.go index 8ff339e08..209b6dcb0 100644 --- a/pkg/tcpip/transport/packet/packet_state_autogen.go +++ b/pkg/tcpip/transport/packet/packet_state_autogen.go @@ -7,84 +7,145 @@ import ( "gvisor.dev/gvisor/pkg/tcpip/buffer" ) +func (x *packet) StateTypeName() string { + return "pkg/tcpip/transport/packet.packet" +} + +func (x *packet) StateFields() []string { + return []string{ + "packetEntry", + "data", + "timestampNS", + "senderAddr", + } +} + func (x *packet) beforeSave() {} -func (x *packet) save(m state.Map) { + +func (x *packet) StateSave(m state.Sink) { x.beforeSave() var data buffer.VectorisedView = x.saveData() - m.SaveValue("data", data) - m.Save("packetEntry", &x.packetEntry) - m.Save("timestampNS", &x.timestampNS) - m.Save("senderAddr", &x.senderAddr) + m.SaveValue(1, data) + m.Save(0, &x.packetEntry) + m.Save(2, &x.timestampNS) + m.Save(3, &x.senderAddr) } func (x *packet) afterLoad() {} -func (x *packet) load(m state.Map) { - m.Load("packetEntry", &x.packetEntry) - m.Load("timestampNS", &x.timestampNS) - m.Load("senderAddr", &x.senderAddr) - m.LoadValue("data", new(buffer.VectorisedView), func(y interface{}) { x.loadData(y.(buffer.VectorisedView)) }) + +func (x *packet) StateLoad(m state.Source) { + m.Load(0, &x.packetEntry) + m.Load(2, &x.timestampNS) + m.Load(3, &x.senderAddr) + m.LoadValue(1, new(buffer.VectorisedView), func(y interface{}) { x.loadData(y.(buffer.VectorisedView)) }) } -func (x *endpoint) save(m state.Map) { +func (x *endpoint) StateTypeName() string { + return "pkg/tcpip/transport/packet.endpoint" +} + +func (x *endpoint) StateFields() []string { + return []string{ + "TransportEndpointInfo", + "netProto", + "waiterQueue", + "cooked", + "rcvList", + "rcvBufSizeMax", + "rcvBufSize", + "rcvClosed", + "sndBufSize", + "closed", + "bound", + } +} + +func (x *endpoint) StateSave(m state.Sink) { x.beforeSave() var rcvBufSizeMax int = x.saveRcvBufSizeMax() - m.SaveValue("rcvBufSizeMax", rcvBufSizeMax) - m.Save("TransportEndpointInfo", &x.TransportEndpointInfo) - m.Save("netProto", &x.netProto) - m.Save("waiterQueue", &x.waiterQueue) - m.Save("cooked", &x.cooked) - m.Save("rcvList", &x.rcvList) - m.Save("rcvBufSize", &x.rcvBufSize) - m.Save("rcvClosed", &x.rcvClosed) - m.Save("sndBufSize", &x.sndBufSize) - m.Save("closed", &x.closed) - m.Save("bound", &x.bound) -} - -func (x *endpoint) load(m state.Map) { - m.Load("TransportEndpointInfo", &x.TransportEndpointInfo) - m.Load("netProto", &x.netProto) - m.Load("waiterQueue", &x.waiterQueue) - m.Load("cooked", &x.cooked) - m.Load("rcvList", &x.rcvList) - m.Load("rcvBufSize", &x.rcvBufSize) - m.Load("rcvClosed", &x.rcvClosed) - m.Load("sndBufSize", &x.sndBufSize) - m.Load("closed", &x.closed) - m.Load("bound", &x.bound) - m.LoadValue("rcvBufSizeMax", new(int), func(y interface{}) { x.loadRcvBufSizeMax(y.(int)) }) + m.SaveValue(5, rcvBufSizeMax) + m.Save(0, &x.TransportEndpointInfo) + m.Save(1, &x.netProto) + m.Save(2, &x.waiterQueue) + m.Save(3, &x.cooked) + m.Save(4, &x.rcvList) + m.Save(6, &x.rcvBufSize) + m.Save(7, &x.rcvClosed) + m.Save(8, &x.sndBufSize) + m.Save(9, &x.closed) + m.Save(10, &x.bound) +} + +func (x *endpoint) StateLoad(m state.Source) { + m.Load(0, &x.TransportEndpointInfo) + m.Load(1, &x.netProto) + m.Load(2, &x.waiterQueue) + m.Load(3, &x.cooked) + m.Load(4, &x.rcvList) + m.Load(6, &x.rcvBufSize) + m.Load(7, &x.rcvClosed) + m.Load(8, &x.sndBufSize) + m.Load(9, &x.closed) + m.Load(10, &x.bound) + m.LoadValue(5, new(int), func(y interface{}) { x.loadRcvBufSizeMax(y.(int)) }) m.AfterLoad(x.afterLoad) } +func (x *packetList) StateTypeName() string { + return "pkg/tcpip/transport/packet.packetList" +} + +func (x *packetList) StateFields() []string { + return []string{ + "head", + "tail", + } +} + func (x *packetList) beforeSave() {} -func (x *packetList) save(m state.Map) { + +func (x *packetList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *packetList) afterLoad() {} -func (x *packetList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *packetList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *packetEntry) StateTypeName() string { + return "pkg/tcpip/transport/packet.packetEntry" +} + +func (x *packetEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *packetEntry) beforeSave() {} -func (x *packetEntry) save(m state.Map) { + +func (x *packetEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *packetEntry) afterLoad() {} -func (x *packetEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *packetEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) } func init() { - state.Register("pkg/tcpip/transport/packet.packet", (*packet)(nil), state.Fns{Save: (*packet).save, Load: (*packet).load}) - state.Register("pkg/tcpip/transport/packet.endpoint", (*endpoint)(nil), state.Fns{Save: (*endpoint).save, Load: (*endpoint).load}) - state.Register("pkg/tcpip/transport/packet.packetList", (*packetList)(nil), state.Fns{Save: (*packetList).save, Load: (*packetList).load}) - state.Register("pkg/tcpip/transport/packet.packetEntry", (*packetEntry)(nil), state.Fns{Save: (*packetEntry).save, Load: (*packetEntry).load}) + state.Register((*packet)(nil)) + state.Register((*endpoint)(nil)) + state.Register((*packetList)(nil)) + state.Register((*packetEntry)(nil)) } diff --git a/pkg/tcpip/transport/raw/raw_packet_list.go b/pkg/tcpip/transport/raw/raw_packet_list.go index 15a8c845b..5f955e86a 100644 --- a/pkg/tcpip/transport/raw/raw_packet_list.go +++ b/pkg/tcpip/transport/raw/raw_packet_list.go @@ -56,7 +56,7 @@ func (l *rawPacketList) Back() *rawPacket { // // NOTE: This is an O(n) operation. func (l *rawPacketList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (rawPacketElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *rawPacketList) Remove(e *rawPacket) { if prev != nil { rawPacketElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { rawPacketElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/tcpip/transport/raw/raw_state_autogen.go b/pkg/tcpip/transport/raw/raw_state_autogen.go index 875ebda36..669477cf9 100644 --- a/pkg/tcpip/transport/raw/raw_state_autogen.go +++ b/pkg/tcpip/transport/raw/raw_state_autogen.go @@ -7,88 +7,151 @@ import ( "gvisor.dev/gvisor/pkg/tcpip/buffer" ) +func (x *rawPacket) StateTypeName() string { + return "pkg/tcpip/transport/raw.rawPacket" +} + +func (x *rawPacket) StateFields() []string { + return []string{ + "rawPacketEntry", + "data", + "timestampNS", + "senderAddr", + } +} + func (x *rawPacket) beforeSave() {} -func (x *rawPacket) save(m state.Map) { + +func (x *rawPacket) StateSave(m state.Sink) { x.beforeSave() var data buffer.VectorisedView = x.saveData() - m.SaveValue("data", data) - m.Save("rawPacketEntry", &x.rawPacketEntry) - m.Save("timestampNS", &x.timestampNS) - m.Save("senderAddr", &x.senderAddr) + m.SaveValue(1, data) + m.Save(0, &x.rawPacketEntry) + m.Save(2, &x.timestampNS) + m.Save(3, &x.senderAddr) } func (x *rawPacket) afterLoad() {} -func (x *rawPacket) load(m state.Map) { - m.Load("rawPacketEntry", &x.rawPacketEntry) - m.Load("timestampNS", &x.timestampNS) - m.Load("senderAddr", &x.senderAddr) - m.LoadValue("data", new(buffer.VectorisedView), func(y interface{}) { x.loadData(y.(buffer.VectorisedView)) }) + +func (x *rawPacket) StateLoad(m state.Source) { + m.Load(0, &x.rawPacketEntry) + m.Load(2, &x.timestampNS) + m.Load(3, &x.senderAddr) + m.LoadValue(1, new(buffer.VectorisedView), func(y interface{}) { x.loadData(y.(buffer.VectorisedView)) }) } -func (x *endpoint) save(m state.Map) { +func (x *endpoint) StateTypeName() string { + return "pkg/tcpip/transport/raw.endpoint" +} + +func (x *endpoint) StateFields() []string { + return []string{ + "TransportEndpointInfo", + "waiterQueue", + "associated", + "rcvList", + "rcvBufSize", + "rcvBufSizeMax", + "rcvClosed", + "sndBufSize", + "sndBufSizeMax", + "closed", + "connected", + "bound", + "owner", + } +} + +func (x *endpoint) StateSave(m state.Sink) { x.beforeSave() var rcvBufSizeMax int = x.saveRcvBufSizeMax() - m.SaveValue("rcvBufSizeMax", rcvBufSizeMax) - m.Save("TransportEndpointInfo", &x.TransportEndpointInfo) - m.Save("waiterQueue", &x.waiterQueue) - m.Save("associated", &x.associated) - m.Save("rcvList", &x.rcvList) - m.Save("rcvBufSize", &x.rcvBufSize) - m.Save("rcvClosed", &x.rcvClosed) - m.Save("sndBufSize", &x.sndBufSize) - m.Save("sndBufSizeMax", &x.sndBufSizeMax) - m.Save("closed", &x.closed) - m.Save("connected", &x.connected) - m.Save("bound", &x.bound) - m.Save("owner", &x.owner) -} - -func (x *endpoint) load(m state.Map) { - m.Load("TransportEndpointInfo", &x.TransportEndpointInfo) - m.Load("waiterQueue", &x.waiterQueue) - m.Load("associated", &x.associated) - m.Load("rcvList", &x.rcvList) - m.Load("rcvBufSize", &x.rcvBufSize) - m.Load("rcvClosed", &x.rcvClosed) - m.Load("sndBufSize", &x.sndBufSize) - m.Load("sndBufSizeMax", &x.sndBufSizeMax) - m.Load("closed", &x.closed) - m.Load("connected", &x.connected) - m.Load("bound", &x.bound) - m.Load("owner", &x.owner) - m.LoadValue("rcvBufSizeMax", new(int), func(y interface{}) { x.loadRcvBufSizeMax(y.(int)) }) + m.SaveValue(5, rcvBufSizeMax) + m.Save(0, &x.TransportEndpointInfo) + m.Save(1, &x.waiterQueue) + m.Save(2, &x.associated) + m.Save(3, &x.rcvList) + m.Save(4, &x.rcvBufSize) + m.Save(6, &x.rcvClosed) + m.Save(7, &x.sndBufSize) + m.Save(8, &x.sndBufSizeMax) + m.Save(9, &x.closed) + m.Save(10, &x.connected) + m.Save(11, &x.bound) + m.Save(12, &x.owner) +} + +func (x *endpoint) StateLoad(m state.Source) { + m.Load(0, &x.TransportEndpointInfo) + m.Load(1, &x.waiterQueue) + m.Load(2, &x.associated) + m.Load(3, &x.rcvList) + m.Load(4, &x.rcvBufSize) + m.Load(6, &x.rcvClosed) + m.Load(7, &x.sndBufSize) + m.Load(8, &x.sndBufSizeMax) + m.Load(9, &x.closed) + m.Load(10, &x.connected) + m.Load(11, &x.bound) + m.Load(12, &x.owner) + m.LoadValue(5, new(int), func(y interface{}) { x.loadRcvBufSizeMax(y.(int)) }) m.AfterLoad(x.afterLoad) } +func (x *rawPacketList) StateTypeName() string { + return "pkg/tcpip/transport/raw.rawPacketList" +} + +func (x *rawPacketList) StateFields() []string { + return []string{ + "head", + "tail", + } +} + func (x *rawPacketList) beforeSave() {} -func (x *rawPacketList) save(m state.Map) { + +func (x *rawPacketList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *rawPacketList) afterLoad() {} -func (x *rawPacketList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *rawPacketList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *rawPacketEntry) StateTypeName() string { + return "pkg/tcpip/transport/raw.rawPacketEntry" +} + +func (x *rawPacketEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *rawPacketEntry) beforeSave() {} -func (x *rawPacketEntry) save(m state.Map) { + +func (x *rawPacketEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *rawPacketEntry) afterLoad() {} -func (x *rawPacketEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *rawPacketEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) } func init() { - state.Register("pkg/tcpip/transport/raw.rawPacket", (*rawPacket)(nil), state.Fns{Save: (*rawPacket).save, Load: (*rawPacket).load}) - state.Register("pkg/tcpip/transport/raw.endpoint", (*endpoint)(nil), state.Fns{Save: (*endpoint).save, Load: (*endpoint).load}) - state.Register("pkg/tcpip/transport/raw.rawPacketList", (*rawPacketList)(nil), state.Fns{Save: (*rawPacketList).save, Load: (*rawPacketList).load}) - state.Register("pkg/tcpip/transport/raw.rawPacketEntry", (*rawPacketEntry)(nil), state.Fns{Save: (*rawPacketEntry).save, Load: (*rawPacketEntry).load}) + state.Register((*rawPacket)(nil)) + state.Register((*endpoint)(nil)) + state.Register((*rawPacketList)(nil)) + state.Register((*rawPacketEntry)(nil)) } diff --git a/pkg/tcpip/transport/tcp/tcp_endpoint_list.go b/pkg/tcpip/transport/tcp/tcp_endpoint_list.go index fb7046d8f..71ae11c81 100644 --- a/pkg/tcpip/transport/tcp/tcp_endpoint_list.go +++ b/pkg/tcpip/transport/tcp/tcp_endpoint_list.go @@ -56,7 +56,7 @@ func (l *endpointList) Back() *endpoint { // // NOTE: This is an O(n) operation. func (l *endpointList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (endpointElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *endpointList) Remove(e *endpoint) { if prev != nil { endpointElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { endpointElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/tcpip/transport/tcp/tcp_segment_list.go b/pkg/tcpip/transport/tcp/tcp_segment_list.go index 21638041c..fcd0c7ec1 100644 --- a/pkg/tcpip/transport/tcp/tcp_segment_list.go +++ b/pkg/tcpip/transport/tcp/tcp_segment_list.go @@ -56,7 +56,7 @@ func (l *segmentList) Back() *segment { // // NOTE: This is an O(n) operation. func (l *segmentList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (segmentElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *segmentList) Remove(e *segment) { if prev != nil { segmentElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { segmentElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/tcpip/transport/tcp/tcp_state_autogen.go b/pkg/tcpip/transport/tcp/tcp_state_autogen.go index 8f9e742fc..4b513121f 100644 --- a/pkg/tcpip/transport/tcp/tcp_state_autogen.go +++ b/pkg/tcpip/transport/tcp/tcp_state_autogen.go @@ -7,543 +7,916 @@ import ( "gvisor.dev/gvisor/pkg/tcpip/buffer" ) +func (x *cubicState) StateTypeName() string { + return "pkg/tcpip/transport/tcp.cubicState" +} + +func (x *cubicState) StateFields() []string { + return []string{ + "wLastMax", + "wMax", + "t", + "numCongestionEvents", + "c", + "k", + "beta", + "wC", + "wEst", + "s", + } +} + func (x *cubicState) beforeSave() {} -func (x *cubicState) save(m state.Map) { + +func (x *cubicState) StateSave(m state.Sink) { x.beforeSave() var t unixTime = x.saveT() - m.SaveValue("t", t) - m.Save("wLastMax", &x.wLastMax) - m.Save("wMax", &x.wMax) - m.Save("numCongestionEvents", &x.numCongestionEvents) - m.Save("c", &x.c) - m.Save("k", &x.k) - m.Save("beta", &x.beta) - m.Save("wC", &x.wC) - m.Save("wEst", &x.wEst) - m.Save("s", &x.s) + m.SaveValue(2, t) + m.Save(0, &x.wLastMax) + m.Save(1, &x.wMax) + m.Save(3, &x.numCongestionEvents) + m.Save(4, &x.c) + m.Save(5, &x.k) + m.Save(6, &x.beta) + m.Save(7, &x.wC) + m.Save(8, &x.wEst) + m.Save(9, &x.s) } func (x *cubicState) afterLoad() {} -func (x *cubicState) load(m state.Map) { - m.Load("wLastMax", &x.wLastMax) - m.Load("wMax", &x.wMax) - m.Load("numCongestionEvents", &x.numCongestionEvents) - m.Load("c", &x.c) - m.Load("k", &x.k) - m.Load("beta", &x.beta) - m.Load("wC", &x.wC) - m.Load("wEst", &x.wEst) - m.Load("s", &x.s) - m.LoadValue("t", new(unixTime), func(y interface{}) { x.loadT(y.(unixTime)) }) + +func (x *cubicState) StateLoad(m state.Source) { + m.Load(0, &x.wLastMax) + m.Load(1, &x.wMax) + m.Load(3, &x.numCongestionEvents) + m.Load(4, &x.c) + m.Load(5, &x.k) + m.Load(6, &x.beta) + m.Load(7, &x.wC) + m.Load(8, &x.wEst) + m.Load(9, &x.s) + m.LoadValue(2, new(unixTime), func(y interface{}) { x.loadT(y.(unixTime)) }) +} + +func (x *SACKInfo) StateTypeName() string { + return "pkg/tcpip/transport/tcp.SACKInfo" +} + +func (x *SACKInfo) StateFields() []string { + return []string{ + "Blocks", + "NumBlocks", + } } func (x *SACKInfo) beforeSave() {} -func (x *SACKInfo) save(m state.Map) { + +func (x *SACKInfo) StateSave(m state.Sink) { x.beforeSave() - m.Save("Blocks", &x.Blocks) - m.Save("NumBlocks", &x.NumBlocks) + m.Save(0, &x.Blocks) + m.Save(1, &x.NumBlocks) } func (x *SACKInfo) afterLoad() {} -func (x *SACKInfo) load(m state.Map) { - m.Load("Blocks", &x.Blocks) - m.Load("NumBlocks", &x.NumBlocks) + +func (x *SACKInfo) StateLoad(m state.Source) { + m.Load(0, &x.Blocks) + m.Load(1, &x.NumBlocks) +} + +func (x *rcvBufAutoTuneParams) StateTypeName() string { + return "pkg/tcpip/transport/tcp.rcvBufAutoTuneParams" +} + +func (x *rcvBufAutoTuneParams) StateFields() []string { + return []string{ + "measureTime", + "copied", + "prevCopied", + "rtt", + "rttMeasureSeqNumber", + "rttMeasureTime", + "disabled", + } } func (x *rcvBufAutoTuneParams) beforeSave() {} -func (x *rcvBufAutoTuneParams) save(m state.Map) { + +func (x *rcvBufAutoTuneParams) StateSave(m state.Sink) { x.beforeSave() var measureTime unixTime = x.saveMeasureTime() - m.SaveValue("measureTime", measureTime) + m.SaveValue(0, measureTime) var rttMeasureTime unixTime = x.saveRttMeasureTime() - m.SaveValue("rttMeasureTime", rttMeasureTime) - m.Save("copied", &x.copied) - m.Save("prevCopied", &x.prevCopied) - m.Save("rtt", &x.rtt) - m.Save("rttMeasureSeqNumber", &x.rttMeasureSeqNumber) - m.Save("disabled", &x.disabled) + m.SaveValue(5, rttMeasureTime) + m.Save(1, &x.copied) + m.Save(2, &x.prevCopied) + m.Save(3, &x.rtt) + m.Save(4, &x.rttMeasureSeqNumber) + m.Save(6, &x.disabled) } func (x *rcvBufAutoTuneParams) afterLoad() {} -func (x *rcvBufAutoTuneParams) load(m state.Map) { - m.Load("copied", &x.copied) - m.Load("prevCopied", &x.prevCopied) - m.Load("rtt", &x.rtt) - m.Load("rttMeasureSeqNumber", &x.rttMeasureSeqNumber) - m.Load("disabled", &x.disabled) - m.LoadValue("measureTime", new(unixTime), func(y interface{}) { x.loadMeasureTime(y.(unixTime)) }) - m.LoadValue("rttMeasureTime", new(unixTime), func(y interface{}) { x.loadRttMeasureTime(y.(unixTime)) }) + +func (x *rcvBufAutoTuneParams) StateLoad(m state.Source) { + m.Load(1, &x.copied) + m.Load(2, &x.prevCopied) + m.Load(3, &x.rtt) + m.Load(4, &x.rttMeasureSeqNumber) + m.Load(6, &x.disabled) + m.LoadValue(0, new(unixTime), func(y interface{}) { x.loadMeasureTime(y.(unixTime)) }) + m.LoadValue(5, new(unixTime), func(y interface{}) { x.loadRttMeasureTime(y.(unixTime)) }) +} + +func (x *EndpointInfo) StateTypeName() string { + return "pkg/tcpip/transport/tcp.EndpointInfo" +} + +func (x *EndpointInfo) StateFields() []string { + return []string{ + "TransportEndpointInfo", + "HardError", + } } func (x *EndpointInfo) beforeSave() {} -func (x *EndpointInfo) save(m state.Map) { + +func (x *EndpointInfo) StateSave(m state.Sink) { x.beforeSave() var HardError string = x.saveHardError() - m.SaveValue("HardError", HardError) - m.Save("TransportEndpointInfo", &x.TransportEndpointInfo) + m.SaveValue(1, HardError) + m.Save(0, &x.TransportEndpointInfo) } func (x *EndpointInfo) afterLoad() {} -func (x *EndpointInfo) load(m state.Map) { - m.Load("TransportEndpointInfo", &x.TransportEndpointInfo) - m.LoadValue("HardError", new(string), func(y interface{}) { x.loadHardError(y.(string)) }) -} -func (x *endpoint) save(m state.Map) { +func (x *EndpointInfo) StateLoad(m state.Source) { + m.Load(0, &x.TransportEndpointInfo) + m.LoadValue(1, new(string), func(y interface{}) { x.loadHardError(y.(string)) }) +} + +func (x *endpoint) StateTypeName() string { + return "pkg/tcpip/transport/tcp.endpoint" +} + +func (x *endpoint) StateFields() []string { + return []string{ + "EndpointInfo", + "waiterQueue", + "uniqueID", + "lastError", + "rcvList", + "rcvClosed", + "rcvBufSize", + "rcvBufUsed", + "rcvAutoParams", + "ownedByUser", + "state", + "boundNICID", + "ttl", + "v6only", + "isConnectNotified", + "broadcast", + "portFlags", + "boundBindToDevice", + "boundPortFlags", + "boundDest", + "effectiveNetProtos", + "workerRunning", + "workerCleanup", + "sendTSOk", + "recentTS", + "tsOffset", + "shutdownFlags", + "sackPermitted", + "sack", + "bindToDevice", + "delay", + "cork", + "scoreboard", + "slowAck", + "segmentQueue", + "synRcvdCount", + "userMSS", + "maxSynRetries", + "windowClamp", + "sndBufSize", + "sndBufUsed", + "sndClosed", + "sndBufInQueue", + "sndQueue", + "cc", + "packetTooBigCount", + "sndMTU", + "keepalive", + "userTimeout", + "deferAccept", + "acceptedChan", + "rcv", + "snd", + "connectingAddress", + "amss", + "sendTOS", + "gso", + "tcpLingerTimeout", + "closed", + "txHash", + "owner", + } +} + +func (x *endpoint) StateSave(m state.Sink) { x.beforeSave() var lastError string = x.saveLastError() - m.SaveValue("lastError", lastError) + m.SaveValue(3, lastError) var state EndpointState = x.saveState() - m.SaveValue("state", state) + m.SaveValue(10, state) var acceptedChan []*endpoint = x.saveAcceptedChan() - m.SaveValue("acceptedChan", acceptedChan) - m.Save("EndpointInfo", &x.EndpointInfo) - m.Save("waiterQueue", &x.waiterQueue) - m.Save("uniqueID", &x.uniqueID) - m.Save("rcvList", &x.rcvList) - m.Save("rcvClosed", &x.rcvClosed) - m.Save("rcvBufSize", &x.rcvBufSize) - m.Save("rcvBufUsed", &x.rcvBufUsed) - m.Save("rcvAutoParams", &x.rcvAutoParams) - m.Save("ownedByUser", &x.ownedByUser) - m.Save("boundNICID", &x.boundNICID) - m.Save("ttl", &x.ttl) - m.Save("v6only", &x.v6only) - m.Save("isConnectNotified", &x.isConnectNotified) - m.Save("broadcast", &x.broadcast) - m.Save("portFlags", &x.portFlags) - m.Save("boundBindToDevice", &x.boundBindToDevice) - m.Save("boundPortFlags", &x.boundPortFlags) - m.Save("boundDest", &x.boundDest) - m.Save("effectiveNetProtos", &x.effectiveNetProtos) - m.Save("workerRunning", &x.workerRunning) - m.Save("workerCleanup", &x.workerCleanup) - m.Save("sendTSOk", &x.sendTSOk) - m.Save("recentTS", &x.recentTS) - m.Save("tsOffset", &x.tsOffset) - m.Save("shutdownFlags", &x.shutdownFlags) - m.Save("sackPermitted", &x.sackPermitted) - m.Save("sack", &x.sack) - m.Save("bindToDevice", &x.bindToDevice) - m.Save("delay", &x.delay) - m.Save("cork", &x.cork) - m.Save("scoreboard", &x.scoreboard) - m.Save("slowAck", &x.slowAck) - m.Save("segmentQueue", &x.segmentQueue) - m.Save("synRcvdCount", &x.synRcvdCount) - m.Save("userMSS", &x.userMSS) - m.Save("maxSynRetries", &x.maxSynRetries) - m.Save("windowClamp", &x.windowClamp) - m.Save("sndBufSize", &x.sndBufSize) - m.Save("sndBufUsed", &x.sndBufUsed) - m.Save("sndClosed", &x.sndClosed) - m.Save("sndBufInQueue", &x.sndBufInQueue) - m.Save("sndQueue", &x.sndQueue) - m.Save("cc", &x.cc) - m.Save("packetTooBigCount", &x.packetTooBigCount) - m.Save("sndMTU", &x.sndMTU) - m.Save("keepalive", &x.keepalive) - m.Save("userTimeout", &x.userTimeout) - m.Save("deferAccept", &x.deferAccept) - m.Save("rcv", &x.rcv) - m.Save("snd", &x.snd) - m.Save("connectingAddress", &x.connectingAddress) - m.Save("amss", &x.amss) - m.Save("sendTOS", &x.sendTOS) - m.Save("gso", &x.gso) - m.Save("tcpLingerTimeout", &x.tcpLingerTimeout) - m.Save("closed", &x.closed) - m.Save("txHash", &x.txHash) - m.Save("owner", &x.owner) -} - -func (x *endpoint) load(m state.Map) { - m.Load("EndpointInfo", &x.EndpointInfo) - m.LoadWait("waiterQueue", &x.waiterQueue) - m.Load("uniqueID", &x.uniqueID) - m.LoadWait("rcvList", &x.rcvList) - m.Load("rcvClosed", &x.rcvClosed) - m.Load("rcvBufSize", &x.rcvBufSize) - m.Load("rcvBufUsed", &x.rcvBufUsed) - m.Load("rcvAutoParams", &x.rcvAutoParams) - m.Load("ownedByUser", &x.ownedByUser) - m.Load("boundNICID", &x.boundNICID) - m.Load("ttl", &x.ttl) - m.Load("v6only", &x.v6only) - m.Load("isConnectNotified", &x.isConnectNotified) - m.Load("broadcast", &x.broadcast) - m.Load("portFlags", &x.portFlags) - m.Load("boundBindToDevice", &x.boundBindToDevice) - m.Load("boundPortFlags", &x.boundPortFlags) - m.Load("boundDest", &x.boundDest) - m.Load("effectiveNetProtos", &x.effectiveNetProtos) - m.Load("workerRunning", &x.workerRunning) - m.Load("workerCleanup", &x.workerCleanup) - m.Load("sendTSOk", &x.sendTSOk) - m.Load("recentTS", &x.recentTS) - m.Load("tsOffset", &x.tsOffset) - m.Load("shutdownFlags", &x.shutdownFlags) - m.Load("sackPermitted", &x.sackPermitted) - m.Load("sack", &x.sack) - m.Load("bindToDevice", &x.bindToDevice) - m.Load("delay", &x.delay) - m.Load("cork", &x.cork) - m.Load("scoreboard", &x.scoreboard) - m.Load("slowAck", &x.slowAck) - m.LoadWait("segmentQueue", &x.segmentQueue) - m.Load("synRcvdCount", &x.synRcvdCount) - m.Load("userMSS", &x.userMSS) - m.Load("maxSynRetries", &x.maxSynRetries) - m.Load("windowClamp", &x.windowClamp) - m.Load("sndBufSize", &x.sndBufSize) - m.Load("sndBufUsed", &x.sndBufUsed) - m.Load("sndClosed", &x.sndClosed) - m.Load("sndBufInQueue", &x.sndBufInQueue) - m.LoadWait("sndQueue", &x.sndQueue) - m.Load("cc", &x.cc) - m.Load("packetTooBigCount", &x.packetTooBigCount) - m.Load("sndMTU", &x.sndMTU) - m.Load("keepalive", &x.keepalive) - m.Load("userTimeout", &x.userTimeout) - m.Load("deferAccept", &x.deferAccept) - m.LoadWait("rcv", &x.rcv) - m.LoadWait("snd", &x.snd) - m.Load("connectingAddress", &x.connectingAddress) - m.Load("amss", &x.amss) - m.Load("sendTOS", &x.sendTOS) - m.Load("gso", &x.gso) - m.Load("tcpLingerTimeout", &x.tcpLingerTimeout) - m.Load("closed", &x.closed) - m.Load("txHash", &x.txHash) - m.Load("owner", &x.owner) - m.LoadValue("lastError", new(string), func(y interface{}) { x.loadLastError(y.(string)) }) - m.LoadValue("state", new(EndpointState), func(y interface{}) { x.loadState(y.(EndpointState)) }) - m.LoadValue("acceptedChan", new([]*endpoint), func(y interface{}) { x.loadAcceptedChan(y.([]*endpoint)) }) + m.SaveValue(50, acceptedChan) + m.Save(0, &x.EndpointInfo) + m.Save(1, &x.waiterQueue) + m.Save(2, &x.uniqueID) + m.Save(4, &x.rcvList) + m.Save(5, &x.rcvClosed) + m.Save(6, &x.rcvBufSize) + m.Save(7, &x.rcvBufUsed) + m.Save(8, &x.rcvAutoParams) + m.Save(9, &x.ownedByUser) + m.Save(11, &x.boundNICID) + m.Save(12, &x.ttl) + m.Save(13, &x.v6only) + m.Save(14, &x.isConnectNotified) + m.Save(15, &x.broadcast) + m.Save(16, &x.portFlags) + m.Save(17, &x.boundBindToDevice) + m.Save(18, &x.boundPortFlags) + m.Save(19, &x.boundDest) + m.Save(20, &x.effectiveNetProtos) + m.Save(21, &x.workerRunning) + m.Save(22, &x.workerCleanup) + m.Save(23, &x.sendTSOk) + m.Save(24, &x.recentTS) + m.Save(25, &x.tsOffset) + m.Save(26, &x.shutdownFlags) + m.Save(27, &x.sackPermitted) + m.Save(28, &x.sack) + m.Save(29, &x.bindToDevice) + m.Save(30, &x.delay) + m.Save(31, &x.cork) + m.Save(32, &x.scoreboard) + m.Save(33, &x.slowAck) + m.Save(34, &x.segmentQueue) + m.Save(35, &x.synRcvdCount) + m.Save(36, &x.userMSS) + m.Save(37, &x.maxSynRetries) + m.Save(38, &x.windowClamp) + m.Save(39, &x.sndBufSize) + m.Save(40, &x.sndBufUsed) + m.Save(41, &x.sndClosed) + m.Save(42, &x.sndBufInQueue) + m.Save(43, &x.sndQueue) + m.Save(44, &x.cc) + m.Save(45, &x.packetTooBigCount) + m.Save(46, &x.sndMTU) + m.Save(47, &x.keepalive) + m.Save(48, &x.userTimeout) + m.Save(49, &x.deferAccept) + m.Save(51, &x.rcv) + m.Save(52, &x.snd) + m.Save(53, &x.connectingAddress) + m.Save(54, &x.amss) + m.Save(55, &x.sendTOS) + m.Save(56, &x.gso) + m.Save(57, &x.tcpLingerTimeout) + m.Save(58, &x.closed) + m.Save(59, &x.txHash) + m.Save(60, &x.owner) +} + +func (x *endpoint) StateLoad(m state.Source) { + m.Load(0, &x.EndpointInfo) + m.LoadWait(1, &x.waiterQueue) + m.Load(2, &x.uniqueID) + m.LoadWait(4, &x.rcvList) + m.Load(5, &x.rcvClosed) + m.Load(6, &x.rcvBufSize) + m.Load(7, &x.rcvBufUsed) + m.Load(8, &x.rcvAutoParams) + m.Load(9, &x.ownedByUser) + m.Load(11, &x.boundNICID) + m.Load(12, &x.ttl) + m.Load(13, &x.v6only) + m.Load(14, &x.isConnectNotified) + m.Load(15, &x.broadcast) + m.Load(16, &x.portFlags) + m.Load(17, &x.boundBindToDevice) + m.Load(18, &x.boundPortFlags) + m.Load(19, &x.boundDest) + m.Load(20, &x.effectiveNetProtos) + m.Load(21, &x.workerRunning) + m.Load(22, &x.workerCleanup) + m.Load(23, &x.sendTSOk) + m.Load(24, &x.recentTS) + m.Load(25, &x.tsOffset) + m.Load(26, &x.shutdownFlags) + m.Load(27, &x.sackPermitted) + m.Load(28, &x.sack) + m.Load(29, &x.bindToDevice) + m.Load(30, &x.delay) + m.Load(31, &x.cork) + m.Load(32, &x.scoreboard) + m.Load(33, &x.slowAck) + m.LoadWait(34, &x.segmentQueue) + m.Load(35, &x.synRcvdCount) + m.Load(36, &x.userMSS) + m.Load(37, &x.maxSynRetries) + m.Load(38, &x.windowClamp) + m.Load(39, &x.sndBufSize) + m.Load(40, &x.sndBufUsed) + m.Load(41, &x.sndClosed) + m.Load(42, &x.sndBufInQueue) + m.LoadWait(43, &x.sndQueue) + m.Load(44, &x.cc) + m.Load(45, &x.packetTooBigCount) + m.Load(46, &x.sndMTU) + m.Load(47, &x.keepalive) + m.Load(48, &x.userTimeout) + m.Load(49, &x.deferAccept) + m.LoadWait(51, &x.rcv) + m.LoadWait(52, &x.snd) + m.Load(53, &x.connectingAddress) + m.Load(54, &x.amss) + m.Load(55, &x.sendTOS) + m.Load(56, &x.gso) + m.Load(57, &x.tcpLingerTimeout) + m.Load(58, &x.closed) + m.Load(59, &x.txHash) + m.Load(60, &x.owner) + m.LoadValue(3, new(string), func(y interface{}) { x.loadLastError(y.(string)) }) + m.LoadValue(10, new(EndpointState), func(y interface{}) { x.loadState(y.(EndpointState)) }) + m.LoadValue(50, new([]*endpoint), func(y interface{}) { x.loadAcceptedChan(y.([]*endpoint)) }) m.AfterLoad(x.afterLoad) } +func (x *keepalive) StateTypeName() string { + return "pkg/tcpip/transport/tcp.keepalive" +} + +func (x *keepalive) StateFields() []string { + return []string{ + "enabled", + "idle", + "interval", + "count", + "unacked", + } +} + func (x *keepalive) beforeSave() {} -func (x *keepalive) save(m state.Map) { + +func (x *keepalive) StateSave(m state.Sink) { x.beforeSave() - m.Save("enabled", &x.enabled) - m.Save("idle", &x.idle) - m.Save("interval", &x.interval) - m.Save("count", &x.count) - m.Save("unacked", &x.unacked) + m.Save(0, &x.enabled) + m.Save(1, &x.idle) + m.Save(2, &x.interval) + m.Save(3, &x.count) + m.Save(4, &x.unacked) } func (x *keepalive) afterLoad() {} -func (x *keepalive) load(m state.Map) { - m.Load("enabled", &x.enabled) - m.Load("idle", &x.idle) - m.Load("interval", &x.interval) - m.Load("count", &x.count) - m.Load("unacked", &x.unacked) + +func (x *keepalive) StateLoad(m state.Source) { + m.Load(0, &x.enabled) + m.Load(1, &x.idle) + m.Load(2, &x.interval) + m.Load(3, &x.count) + m.Load(4, &x.unacked) +} + +func (x *receiver) StateTypeName() string { + return "pkg/tcpip/transport/tcp.receiver" +} + +func (x *receiver) StateFields() []string { + return []string{ + "ep", + "rcvNxt", + "rcvAcc", + "rcvWnd", + "rcvWndScale", + "closed", + "pendingRcvdSegments", + "pendingBufUsed", + "pendingBufSize", + "lastRcvdAckTime", + } } func (x *receiver) beforeSave() {} -func (x *receiver) save(m state.Map) { + +func (x *receiver) StateSave(m state.Sink) { x.beforeSave() var lastRcvdAckTime unixTime = x.saveLastRcvdAckTime() - m.SaveValue("lastRcvdAckTime", lastRcvdAckTime) - m.Save("ep", &x.ep) - m.Save("rcvNxt", &x.rcvNxt) - m.Save("rcvAcc", &x.rcvAcc) - m.Save("rcvWnd", &x.rcvWnd) - m.Save("rcvWndScale", &x.rcvWndScale) - m.Save("closed", &x.closed) - m.Save("pendingRcvdSegments", &x.pendingRcvdSegments) - m.Save("pendingBufUsed", &x.pendingBufUsed) - m.Save("pendingBufSize", &x.pendingBufSize) + m.SaveValue(9, lastRcvdAckTime) + m.Save(0, &x.ep) + m.Save(1, &x.rcvNxt) + m.Save(2, &x.rcvAcc) + m.Save(3, &x.rcvWnd) + m.Save(4, &x.rcvWndScale) + m.Save(5, &x.closed) + m.Save(6, &x.pendingRcvdSegments) + m.Save(7, &x.pendingBufUsed) + m.Save(8, &x.pendingBufSize) } func (x *receiver) afterLoad() {} -func (x *receiver) load(m state.Map) { - m.Load("ep", &x.ep) - m.Load("rcvNxt", &x.rcvNxt) - m.Load("rcvAcc", &x.rcvAcc) - m.Load("rcvWnd", &x.rcvWnd) - m.Load("rcvWndScale", &x.rcvWndScale) - m.Load("closed", &x.closed) - m.Load("pendingRcvdSegments", &x.pendingRcvdSegments) - m.Load("pendingBufUsed", &x.pendingBufUsed) - m.Load("pendingBufSize", &x.pendingBufSize) - m.LoadValue("lastRcvdAckTime", new(unixTime), func(y interface{}) { x.loadLastRcvdAckTime(y.(unixTime)) }) + +func (x *receiver) StateLoad(m state.Source) { + m.Load(0, &x.ep) + m.Load(1, &x.rcvNxt) + m.Load(2, &x.rcvAcc) + m.Load(3, &x.rcvWnd) + m.Load(4, &x.rcvWndScale) + m.Load(5, &x.closed) + m.Load(6, &x.pendingRcvdSegments) + m.Load(7, &x.pendingBufUsed) + m.Load(8, &x.pendingBufSize) + m.LoadValue(9, new(unixTime), func(y interface{}) { x.loadLastRcvdAckTime(y.(unixTime)) }) +} + +func (x *renoState) StateTypeName() string { + return "pkg/tcpip/transport/tcp.renoState" +} + +func (x *renoState) StateFields() []string { + return []string{ + "s", + } } func (x *renoState) beforeSave() {} -func (x *renoState) save(m state.Map) { + +func (x *renoState) StateSave(m state.Sink) { x.beforeSave() - m.Save("s", &x.s) + m.Save(0, &x.s) } func (x *renoState) afterLoad() {} -func (x *renoState) load(m state.Map) { - m.Load("s", &x.s) + +func (x *renoState) StateLoad(m state.Source) { + m.Load(0, &x.s) +} + +func (x *SACKScoreboard) StateTypeName() string { + return "pkg/tcpip/transport/tcp.SACKScoreboard" +} + +func (x *SACKScoreboard) StateFields() []string { + return []string{ + "smss", + "maxSACKED", + } } func (x *SACKScoreboard) beforeSave() {} -func (x *SACKScoreboard) save(m state.Map) { + +func (x *SACKScoreboard) StateSave(m state.Sink) { x.beforeSave() - m.Save("smss", &x.smss) - m.Save("maxSACKED", &x.maxSACKED) + m.Save(0, &x.smss) + m.Save(1, &x.maxSACKED) } func (x *SACKScoreboard) afterLoad() {} -func (x *SACKScoreboard) load(m state.Map) { - m.Load("smss", &x.smss) - m.Load("maxSACKED", &x.maxSACKED) + +func (x *SACKScoreboard) StateLoad(m state.Source) { + m.Load(0, &x.smss) + m.Load(1, &x.maxSACKED) +} + +func (x *segment) StateTypeName() string { + return "pkg/tcpip/transport/tcp.segment" +} + +func (x *segment) StateFields() []string { + return []string{ + "segmentEntry", + "refCnt", + "data", + "hdr", + "viewToDeliver", + "sequenceNumber", + "ackNumber", + "flags", + "window", + "csum", + "csumValid", + "parsedOptions", + "options", + "hasNewSACKInfo", + "rcvdTime", + "xmitTime", + "xmitCount", + } } func (x *segment) beforeSave() {} -func (x *segment) save(m state.Map) { + +func (x *segment) StateSave(m state.Sink) { x.beforeSave() var data buffer.VectorisedView = x.saveData() - m.SaveValue("data", data) + m.SaveValue(2, data) var options []byte = x.saveOptions() - m.SaveValue("options", options) + m.SaveValue(12, options) var rcvdTime unixTime = x.saveRcvdTime() - m.SaveValue("rcvdTime", rcvdTime) + m.SaveValue(14, rcvdTime) var xmitTime unixTime = x.saveXmitTime() - m.SaveValue("xmitTime", xmitTime) - m.Save("segmentEntry", &x.segmentEntry) - m.Save("refCnt", &x.refCnt) - m.Save("hdr", &x.hdr) - m.Save("viewToDeliver", &x.viewToDeliver) - m.Save("sequenceNumber", &x.sequenceNumber) - m.Save("ackNumber", &x.ackNumber) - m.Save("flags", &x.flags) - m.Save("window", &x.window) - m.Save("csum", &x.csum) - m.Save("csumValid", &x.csumValid) - m.Save("parsedOptions", &x.parsedOptions) - m.Save("hasNewSACKInfo", &x.hasNewSACKInfo) - m.Save("xmitCount", &x.xmitCount) + m.SaveValue(15, xmitTime) + m.Save(0, &x.segmentEntry) + m.Save(1, &x.refCnt) + m.Save(3, &x.hdr) + m.Save(4, &x.viewToDeliver) + m.Save(5, &x.sequenceNumber) + m.Save(6, &x.ackNumber) + m.Save(7, &x.flags) + m.Save(8, &x.window) + m.Save(9, &x.csum) + m.Save(10, &x.csumValid) + m.Save(11, &x.parsedOptions) + m.Save(13, &x.hasNewSACKInfo) + m.Save(16, &x.xmitCount) } func (x *segment) afterLoad() {} -func (x *segment) load(m state.Map) { - m.Load("segmentEntry", &x.segmentEntry) - m.Load("refCnt", &x.refCnt) - m.Load("hdr", &x.hdr) - m.Load("viewToDeliver", &x.viewToDeliver) - m.Load("sequenceNumber", &x.sequenceNumber) - m.Load("ackNumber", &x.ackNumber) - m.Load("flags", &x.flags) - m.Load("window", &x.window) - m.Load("csum", &x.csum) - m.Load("csumValid", &x.csumValid) - m.Load("parsedOptions", &x.parsedOptions) - m.Load("hasNewSACKInfo", &x.hasNewSACKInfo) - m.Load("xmitCount", &x.xmitCount) - m.LoadValue("data", new(buffer.VectorisedView), func(y interface{}) { x.loadData(y.(buffer.VectorisedView)) }) - m.LoadValue("options", new([]byte), func(y interface{}) { x.loadOptions(y.([]byte)) }) - m.LoadValue("rcvdTime", new(unixTime), func(y interface{}) { x.loadRcvdTime(y.(unixTime)) }) - m.LoadValue("xmitTime", new(unixTime), func(y interface{}) { x.loadXmitTime(y.(unixTime)) }) + +func (x *segment) StateLoad(m state.Source) { + m.Load(0, &x.segmentEntry) + m.Load(1, &x.refCnt) + m.Load(3, &x.hdr) + m.Load(4, &x.viewToDeliver) + m.Load(5, &x.sequenceNumber) + m.Load(6, &x.ackNumber) + m.Load(7, &x.flags) + m.Load(8, &x.window) + m.Load(9, &x.csum) + m.Load(10, &x.csumValid) + m.Load(11, &x.parsedOptions) + m.Load(13, &x.hasNewSACKInfo) + m.Load(16, &x.xmitCount) + m.LoadValue(2, new(buffer.VectorisedView), func(y interface{}) { x.loadData(y.(buffer.VectorisedView)) }) + m.LoadValue(12, new([]byte), func(y interface{}) { x.loadOptions(y.([]byte)) }) + m.LoadValue(14, new(unixTime), func(y interface{}) { x.loadRcvdTime(y.(unixTime)) }) + m.LoadValue(15, new(unixTime), func(y interface{}) { x.loadXmitTime(y.(unixTime)) }) +} + +func (x *segmentQueue) StateTypeName() string { + return "pkg/tcpip/transport/tcp.segmentQueue" +} + +func (x *segmentQueue) StateFields() []string { + return []string{ + "list", + "limit", + "used", + } } func (x *segmentQueue) beforeSave() {} -func (x *segmentQueue) save(m state.Map) { + +func (x *segmentQueue) StateSave(m state.Sink) { x.beforeSave() - m.Save("list", &x.list) - m.Save("limit", &x.limit) - m.Save("used", &x.used) + m.Save(0, &x.list) + m.Save(1, &x.limit) + m.Save(2, &x.used) } func (x *segmentQueue) afterLoad() {} -func (x *segmentQueue) load(m state.Map) { - m.LoadWait("list", &x.list) - m.Load("limit", &x.limit) - m.Load("used", &x.used) + +func (x *segmentQueue) StateLoad(m state.Source) { + m.LoadWait(0, &x.list) + m.Load(1, &x.limit) + m.Load(2, &x.used) +} + +func (x *sender) StateTypeName() string { + return "pkg/tcpip/transport/tcp.sender" +} + +func (x *sender) StateFields() []string { + return []string{ + "ep", + "lastSendTime", + "dupAckCount", + "fr", + "sndCwnd", + "sndSsthresh", + "sndCAAckCount", + "outstanding", + "sndWnd", + "sndUna", + "sndNxt", + "rttMeasureSeqNum", + "rttMeasureTime", + "firstRetransmittedSegXmitTime", + "closed", + "writeNext", + "writeList", + "rtt", + "rto", + "minRTO", + "maxRTO", + "maxRetries", + "maxPayloadSize", + "gso", + "sndWndScale", + "maxSentAck", + "state", + "cc", + } } func (x *sender) beforeSave() {} -func (x *sender) save(m state.Map) { + +func (x *sender) StateSave(m state.Sink) { x.beforeSave() var lastSendTime unixTime = x.saveLastSendTime() - m.SaveValue("lastSendTime", lastSendTime) + m.SaveValue(1, lastSendTime) var rttMeasureTime unixTime = x.saveRttMeasureTime() - m.SaveValue("rttMeasureTime", rttMeasureTime) + m.SaveValue(12, rttMeasureTime) var firstRetransmittedSegXmitTime unixTime = x.saveFirstRetransmittedSegXmitTime() - m.SaveValue("firstRetransmittedSegXmitTime", firstRetransmittedSegXmitTime) - m.Save("ep", &x.ep) - m.Save("dupAckCount", &x.dupAckCount) - m.Save("fr", &x.fr) - m.Save("sndCwnd", &x.sndCwnd) - m.Save("sndSsthresh", &x.sndSsthresh) - m.Save("sndCAAckCount", &x.sndCAAckCount) - m.Save("outstanding", &x.outstanding) - m.Save("sndWnd", &x.sndWnd) - m.Save("sndUna", &x.sndUna) - m.Save("sndNxt", &x.sndNxt) - m.Save("rttMeasureSeqNum", &x.rttMeasureSeqNum) - m.Save("closed", &x.closed) - m.Save("writeNext", &x.writeNext) - m.Save("writeList", &x.writeList) - m.Save("rtt", &x.rtt) - m.Save("rto", &x.rto) - m.Save("minRTO", &x.minRTO) - m.Save("maxRTO", &x.maxRTO) - m.Save("maxRetries", &x.maxRetries) - m.Save("maxPayloadSize", &x.maxPayloadSize) - m.Save("gso", &x.gso) - m.Save("sndWndScale", &x.sndWndScale) - m.Save("maxSentAck", &x.maxSentAck) - m.Save("state", &x.state) - m.Save("cc", &x.cc) -} - -func (x *sender) load(m state.Map) { - m.Load("ep", &x.ep) - m.Load("dupAckCount", &x.dupAckCount) - m.Load("fr", &x.fr) - m.Load("sndCwnd", &x.sndCwnd) - m.Load("sndSsthresh", &x.sndSsthresh) - m.Load("sndCAAckCount", &x.sndCAAckCount) - m.Load("outstanding", &x.outstanding) - m.Load("sndWnd", &x.sndWnd) - m.Load("sndUna", &x.sndUna) - m.Load("sndNxt", &x.sndNxt) - m.Load("rttMeasureSeqNum", &x.rttMeasureSeqNum) - m.Load("closed", &x.closed) - m.Load("writeNext", &x.writeNext) - m.Load("writeList", &x.writeList) - m.Load("rtt", &x.rtt) - m.Load("rto", &x.rto) - m.Load("minRTO", &x.minRTO) - m.Load("maxRTO", &x.maxRTO) - m.Load("maxRetries", &x.maxRetries) - m.Load("maxPayloadSize", &x.maxPayloadSize) - m.Load("gso", &x.gso) - m.Load("sndWndScale", &x.sndWndScale) - m.Load("maxSentAck", &x.maxSentAck) - m.Load("state", &x.state) - m.Load("cc", &x.cc) - m.LoadValue("lastSendTime", new(unixTime), func(y interface{}) { x.loadLastSendTime(y.(unixTime)) }) - m.LoadValue("rttMeasureTime", new(unixTime), func(y interface{}) { x.loadRttMeasureTime(y.(unixTime)) }) - m.LoadValue("firstRetransmittedSegXmitTime", new(unixTime), func(y interface{}) { x.loadFirstRetransmittedSegXmitTime(y.(unixTime)) }) + m.SaveValue(13, firstRetransmittedSegXmitTime) + m.Save(0, &x.ep) + m.Save(2, &x.dupAckCount) + m.Save(3, &x.fr) + m.Save(4, &x.sndCwnd) + m.Save(5, &x.sndSsthresh) + m.Save(6, &x.sndCAAckCount) + m.Save(7, &x.outstanding) + m.Save(8, &x.sndWnd) + m.Save(9, &x.sndUna) + m.Save(10, &x.sndNxt) + m.Save(11, &x.rttMeasureSeqNum) + m.Save(14, &x.closed) + m.Save(15, &x.writeNext) + m.Save(16, &x.writeList) + m.Save(17, &x.rtt) + m.Save(18, &x.rto) + m.Save(19, &x.minRTO) + m.Save(20, &x.maxRTO) + m.Save(21, &x.maxRetries) + m.Save(22, &x.maxPayloadSize) + m.Save(23, &x.gso) + m.Save(24, &x.sndWndScale) + m.Save(25, &x.maxSentAck) + m.Save(26, &x.state) + m.Save(27, &x.cc) +} + +func (x *sender) StateLoad(m state.Source) { + m.Load(0, &x.ep) + m.Load(2, &x.dupAckCount) + m.Load(3, &x.fr) + m.Load(4, &x.sndCwnd) + m.Load(5, &x.sndSsthresh) + m.Load(6, &x.sndCAAckCount) + m.Load(7, &x.outstanding) + m.Load(8, &x.sndWnd) + m.Load(9, &x.sndUna) + m.Load(10, &x.sndNxt) + m.Load(11, &x.rttMeasureSeqNum) + m.Load(14, &x.closed) + m.Load(15, &x.writeNext) + m.Load(16, &x.writeList) + m.Load(17, &x.rtt) + m.Load(18, &x.rto) + m.Load(19, &x.minRTO) + m.Load(20, &x.maxRTO) + m.Load(21, &x.maxRetries) + m.Load(22, &x.maxPayloadSize) + m.Load(23, &x.gso) + m.Load(24, &x.sndWndScale) + m.Load(25, &x.maxSentAck) + m.Load(26, &x.state) + m.Load(27, &x.cc) + m.LoadValue(1, new(unixTime), func(y interface{}) { x.loadLastSendTime(y.(unixTime)) }) + m.LoadValue(12, new(unixTime), func(y interface{}) { x.loadRttMeasureTime(y.(unixTime)) }) + m.LoadValue(13, new(unixTime), func(y interface{}) { x.loadFirstRetransmittedSegXmitTime(y.(unixTime)) }) m.AfterLoad(x.afterLoad) } +func (x *rtt) StateTypeName() string { + return "pkg/tcpip/transport/tcp.rtt" +} + +func (x *rtt) StateFields() []string { + return []string{ + "srtt", + "rttvar", + "srttInited", + } +} + func (x *rtt) beforeSave() {} -func (x *rtt) save(m state.Map) { + +func (x *rtt) StateSave(m state.Sink) { x.beforeSave() - m.Save("srtt", &x.srtt) - m.Save("rttvar", &x.rttvar) - m.Save("srttInited", &x.srttInited) + m.Save(0, &x.srtt) + m.Save(1, &x.rttvar) + m.Save(2, &x.srttInited) } func (x *rtt) afterLoad() {} -func (x *rtt) load(m state.Map) { - m.Load("srtt", &x.srtt) - m.Load("rttvar", &x.rttvar) - m.Load("srttInited", &x.srttInited) + +func (x *rtt) StateLoad(m state.Source) { + m.Load(0, &x.srtt) + m.Load(1, &x.rttvar) + m.Load(2, &x.srttInited) +} + +func (x *fastRecovery) StateTypeName() string { + return "pkg/tcpip/transport/tcp.fastRecovery" +} + +func (x *fastRecovery) StateFields() []string { + return []string{ + "active", + "first", + "last", + "maxCwnd", + "highRxt", + "rescueRxt", + } } func (x *fastRecovery) beforeSave() {} -func (x *fastRecovery) save(m state.Map) { + +func (x *fastRecovery) StateSave(m state.Sink) { x.beforeSave() - m.Save("active", &x.active) - m.Save("first", &x.first) - m.Save("last", &x.last) - m.Save("maxCwnd", &x.maxCwnd) - m.Save("highRxt", &x.highRxt) - m.Save("rescueRxt", &x.rescueRxt) + m.Save(0, &x.active) + m.Save(1, &x.first) + m.Save(2, &x.last) + m.Save(3, &x.maxCwnd) + m.Save(4, &x.highRxt) + m.Save(5, &x.rescueRxt) } func (x *fastRecovery) afterLoad() {} -func (x *fastRecovery) load(m state.Map) { - m.Load("active", &x.active) - m.Load("first", &x.first) - m.Load("last", &x.last) - m.Load("maxCwnd", &x.maxCwnd) - m.Load("highRxt", &x.highRxt) - m.Load("rescueRxt", &x.rescueRxt) + +func (x *fastRecovery) StateLoad(m state.Source) { + m.Load(0, &x.active) + m.Load(1, &x.first) + m.Load(2, &x.last) + m.Load(3, &x.maxCwnd) + m.Load(4, &x.highRxt) + m.Load(5, &x.rescueRxt) +} + +func (x *unixTime) StateTypeName() string { + return "pkg/tcpip/transport/tcp.unixTime" +} + +func (x *unixTime) StateFields() []string { + return []string{ + "second", + "nano", + } } func (x *unixTime) beforeSave() {} -func (x *unixTime) save(m state.Map) { + +func (x *unixTime) StateSave(m state.Sink) { x.beforeSave() - m.Save("second", &x.second) - m.Save("nano", &x.nano) + m.Save(0, &x.second) + m.Save(1, &x.nano) } func (x *unixTime) afterLoad() {} -func (x *unixTime) load(m state.Map) { - m.Load("second", &x.second) - m.Load("nano", &x.nano) + +func (x *unixTime) StateLoad(m state.Source) { + m.Load(0, &x.second) + m.Load(1, &x.nano) +} + +func (x *endpointList) StateTypeName() string { + return "pkg/tcpip/transport/tcp.endpointList" +} + +func (x *endpointList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *endpointList) beforeSave() {} -func (x *endpointList) save(m state.Map) { + +func (x *endpointList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *endpointList) afterLoad() {} -func (x *endpointList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *endpointList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *endpointEntry) StateTypeName() string { + return "pkg/tcpip/transport/tcp.endpointEntry" +} + +func (x *endpointEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *endpointEntry) beforeSave() {} -func (x *endpointEntry) save(m state.Map) { + +func (x *endpointEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *endpointEntry) afterLoad() {} -func (x *endpointEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *endpointEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) +} + +func (x *segmentList) StateTypeName() string { + return "pkg/tcpip/transport/tcp.segmentList" +} + +func (x *segmentList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *segmentList) beforeSave() {} -func (x *segmentList) save(m state.Map) { + +func (x *segmentList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *segmentList) afterLoad() {} -func (x *segmentList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *segmentList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *segmentEntry) StateTypeName() string { + return "pkg/tcpip/transport/tcp.segmentEntry" +} + +func (x *segmentEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *segmentEntry) beforeSave() {} -func (x *segmentEntry) save(m state.Map) { + +func (x *segmentEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *segmentEntry) afterLoad() {} -func (x *segmentEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *segmentEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) } func init() { - state.Register("pkg/tcpip/transport/tcp.cubicState", (*cubicState)(nil), state.Fns{Save: (*cubicState).save, Load: (*cubicState).load}) - state.Register("pkg/tcpip/transport/tcp.SACKInfo", (*SACKInfo)(nil), state.Fns{Save: (*SACKInfo).save, Load: (*SACKInfo).load}) - state.Register("pkg/tcpip/transport/tcp.rcvBufAutoTuneParams", (*rcvBufAutoTuneParams)(nil), state.Fns{Save: (*rcvBufAutoTuneParams).save, Load: (*rcvBufAutoTuneParams).load}) - state.Register("pkg/tcpip/transport/tcp.EndpointInfo", (*EndpointInfo)(nil), state.Fns{Save: (*EndpointInfo).save, Load: (*EndpointInfo).load}) - state.Register("pkg/tcpip/transport/tcp.endpoint", (*endpoint)(nil), state.Fns{Save: (*endpoint).save, Load: (*endpoint).load}) - state.Register("pkg/tcpip/transport/tcp.keepalive", (*keepalive)(nil), state.Fns{Save: (*keepalive).save, Load: (*keepalive).load}) - state.Register("pkg/tcpip/transport/tcp.receiver", (*receiver)(nil), state.Fns{Save: (*receiver).save, Load: (*receiver).load}) - state.Register("pkg/tcpip/transport/tcp.renoState", (*renoState)(nil), state.Fns{Save: (*renoState).save, Load: (*renoState).load}) - state.Register("pkg/tcpip/transport/tcp.SACKScoreboard", (*SACKScoreboard)(nil), state.Fns{Save: (*SACKScoreboard).save, Load: (*SACKScoreboard).load}) - state.Register("pkg/tcpip/transport/tcp.segment", (*segment)(nil), state.Fns{Save: (*segment).save, Load: (*segment).load}) - state.Register("pkg/tcpip/transport/tcp.segmentQueue", (*segmentQueue)(nil), state.Fns{Save: (*segmentQueue).save, Load: (*segmentQueue).load}) - state.Register("pkg/tcpip/transport/tcp.sender", (*sender)(nil), state.Fns{Save: (*sender).save, Load: (*sender).load}) - state.Register("pkg/tcpip/transport/tcp.rtt", (*rtt)(nil), state.Fns{Save: (*rtt).save, Load: (*rtt).load}) - state.Register("pkg/tcpip/transport/tcp.fastRecovery", (*fastRecovery)(nil), state.Fns{Save: (*fastRecovery).save, Load: (*fastRecovery).load}) - state.Register("pkg/tcpip/transport/tcp.unixTime", (*unixTime)(nil), state.Fns{Save: (*unixTime).save, Load: (*unixTime).load}) - state.Register("pkg/tcpip/transport/tcp.endpointList", (*endpointList)(nil), state.Fns{Save: (*endpointList).save, Load: (*endpointList).load}) - state.Register("pkg/tcpip/transport/tcp.endpointEntry", (*endpointEntry)(nil), state.Fns{Save: (*endpointEntry).save, Load: (*endpointEntry).load}) - state.Register("pkg/tcpip/transport/tcp.segmentList", (*segmentList)(nil), state.Fns{Save: (*segmentList).save, Load: (*segmentList).load}) - state.Register("pkg/tcpip/transport/tcp.segmentEntry", (*segmentEntry)(nil), state.Fns{Save: (*segmentEntry).save, Load: (*segmentEntry).load}) + state.Register((*cubicState)(nil)) + state.Register((*SACKInfo)(nil)) + state.Register((*rcvBufAutoTuneParams)(nil)) + state.Register((*EndpointInfo)(nil)) + state.Register((*endpoint)(nil)) + state.Register((*keepalive)(nil)) + state.Register((*receiver)(nil)) + state.Register((*renoState)(nil)) + state.Register((*SACKScoreboard)(nil)) + state.Register((*segment)(nil)) + state.Register((*segmentQueue)(nil)) + state.Register((*sender)(nil)) + state.Register((*rtt)(nil)) + state.Register((*fastRecovery)(nil)) + state.Register((*unixTime)(nil)) + state.Register((*endpointList)(nil)) + state.Register((*endpointEntry)(nil)) + state.Register((*segmentList)(nil)) + state.Register((*segmentEntry)(nil)) } diff --git a/pkg/tcpip/transport/udp/udp_packet_list.go b/pkg/tcpip/transport/udp/udp_packet_list.go index a6513e1e4..5436b9de1 100644 --- a/pkg/tcpip/transport/udp/udp_packet_list.go +++ b/pkg/tcpip/transport/udp/udp_packet_list.go @@ -56,7 +56,7 @@ func (l *udpPacketList) Back() *udpPacket { // // NOTE: This is an O(n) operation. func (l *udpPacketList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (udpPacketElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *udpPacketList) Remove(e *udpPacket) { if prev != nil { udpPacketElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { udpPacketElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/tcpip/transport/udp/udp_state_autogen.go b/pkg/tcpip/transport/udp/udp_state_autogen.go index 0dba38a58..943022c38 100644 --- a/pkg/tcpip/transport/udp/udp_state_autogen.go +++ b/pkg/tcpip/transport/udp/udp_state_autogen.go @@ -7,145 +7,242 @@ import ( "gvisor.dev/gvisor/pkg/tcpip/buffer" ) +func (x *udpPacket) StateTypeName() string { + return "pkg/tcpip/transport/udp.udpPacket" +} + +func (x *udpPacket) StateFields() []string { + return []string{ + "udpPacketEntry", + "senderAddress", + "packetInfo", + "data", + "timestamp", + "tos", + } +} + func (x *udpPacket) beforeSave() {} -func (x *udpPacket) save(m state.Map) { + +func (x *udpPacket) StateSave(m state.Sink) { x.beforeSave() var data buffer.VectorisedView = x.saveData() - m.SaveValue("data", data) - m.Save("udpPacketEntry", &x.udpPacketEntry) - m.Save("senderAddress", &x.senderAddress) - m.Save("packetInfo", &x.packetInfo) - m.Save("timestamp", &x.timestamp) - m.Save("tos", &x.tos) + m.SaveValue(3, data) + m.Save(0, &x.udpPacketEntry) + m.Save(1, &x.senderAddress) + m.Save(2, &x.packetInfo) + m.Save(4, &x.timestamp) + m.Save(5, &x.tos) } func (x *udpPacket) afterLoad() {} -func (x *udpPacket) load(m state.Map) { - m.Load("udpPacketEntry", &x.udpPacketEntry) - m.Load("senderAddress", &x.senderAddress) - m.Load("packetInfo", &x.packetInfo) - m.Load("timestamp", &x.timestamp) - m.Load("tos", &x.tos) - m.LoadValue("data", new(buffer.VectorisedView), func(y interface{}) { x.loadData(y.(buffer.VectorisedView)) }) + +func (x *udpPacket) StateLoad(m state.Source) { + m.Load(0, &x.udpPacketEntry) + m.Load(1, &x.senderAddress) + m.Load(2, &x.packetInfo) + m.Load(4, &x.timestamp) + m.Load(5, &x.tos) + m.LoadValue(3, new(buffer.VectorisedView), func(y interface{}) { x.loadData(y.(buffer.VectorisedView)) }) +} + +func (x *endpoint) StateTypeName() string { + return "pkg/tcpip/transport/udp.endpoint" } -func (x *endpoint) save(m state.Map) { +func (x *endpoint) StateFields() []string { + return []string{ + "TransportEndpointInfo", + "waiterQueue", + "uniqueID", + "rcvReady", + "rcvList", + "rcvBufSizeMax", + "rcvBufSize", + "rcvClosed", + "sndBufSize", + "sndBufSizeMax", + "state", + "dstPort", + "v6only", + "ttl", + "multicastTTL", + "multicastAddr", + "multicastNICID", + "multicastLoop", + "portFlags", + "bindToDevice", + "broadcast", + "lastError", + "boundBindToDevice", + "boundPortFlags", + "sendTOS", + "receiveTOS", + "receiveTClass", + "receiveIPPacketInfo", + "shutdownFlags", + "multicastMemberships", + "effectiveNetProtos", + "owner", + } +} + +func (x *endpoint) StateSave(m state.Sink) { x.beforeSave() var rcvBufSizeMax int = x.saveRcvBufSizeMax() - m.SaveValue("rcvBufSizeMax", rcvBufSizeMax) + m.SaveValue(5, rcvBufSizeMax) var lastError string = x.saveLastError() - m.SaveValue("lastError", lastError) - m.Save("TransportEndpointInfo", &x.TransportEndpointInfo) - m.Save("waiterQueue", &x.waiterQueue) - m.Save("uniqueID", &x.uniqueID) - m.Save("rcvReady", &x.rcvReady) - m.Save("rcvList", &x.rcvList) - m.Save("rcvBufSize", &x.rcvBufSize) - m.Save("rcvClosed", &x.rcvClosed) - m.Save("sndBufSize", &x.sndBufSize) - m.Save("sndBufSizeMax", &x.sndBufSizeMax) - m.Save("state", &x.state) - m.Save("dstPort", &x.dstPort) - m.Save("v6only", &x.v6only) - m.Save("ttl", &x.ttl) - m.Save("multicastTTL", &x.multicastTTL) - m.Save("multicastAddr", &x.multicastAddr) - m.Save("multicastNICID", &x.multicastNICID) - m.Save("multicastLoop", &x.multicastLoop) - m.Save("portFlags", &x.portFlags) - m.Save("bindToDevice", &x.bindToDevice) - m.Save("broadcast", &x.broadcast) - m.Save("boundBindToDevice", &x.boundBindToDevice) - m.Save("boundPortFlags", &x.boundPortFlags) - m.Save("sendTOS", &x.sendTOS) - m.Save("receiveTOS", &x.receiveTOS) - m.Save("receiveTClass", &x.receiveTClass) - m.Save("receiveIPPacketInfo", &x.receiveIPPacketInfo) - m.Save("shutdownFlags", &x.shutdownFlags) - m.Save("multicastMemberships", &x.multicastMemberships) - m.Save("effectiveNetProtos", &x.effectiveNetProtos) - m.Save("owner", &x.owner) -} - -func (x *endpoint) load(m state.Map) { - m.Load("TransportEndpointInfo", &x.TransportEndpointInfo) - m.Load("waiterQueue", &x.waiterQueue) - m.Load("uniqueID", &x.uniqueID) - m.Load("rcvReady", &x.rcvReady) - m.Load("rcvList", &x.rcvList) - m.Load("rcvBufSize", &x.rcvBufSize) - m.Load("rcvClosed", &x.rcvClosed) - m.Load("sndBufSize", &x.sndBufSize) - m.Load("sndBufSizeMax", &x.sndBufSizeMax) - m.Load("state", &x.state) - m.Load("dstPort", &x.dstPort) - m.Load("v6only", &x.v6only) - m.Load("ttl", &x.ttl) - m.Load("multicastTTL", &x.multicastTTL) - m.Load("multicastAddr", &x.multicastAddr) - m.Load("multicastNICID", &x.multicastNICID) - m.Load("multicastLoop", &x.multicastLoop) - m.Load("portFlags", &x.portFlags) - m.Load("bindToDevice", &x.bindToDevice) - m.Load("broadcast", &x.broadcast) - m.Load("boundBindToDevice", &x.boundBindToDevice) - m.Load("boundPortFlags", &x.boundPortFlags) - m.Load("sendTOS", &x.sendTOS) - m.Load("receiveTOS", &x.receiveTOS) - m.Load("receiveTClass", &x.receiveTClass) - m.Load("receiveIPPacketInfo", &x.receiveIPPacketInfo) - m.Load("shutdownFlags", &x.shutdownFlags) - m.Load("multicastMemberships", &x.multicastMemberships) - m.Load("effectiveNetProtos", &x.effectiveNetProtos) - m.Load("owner", &x.owner) - m.LoadValue("rcvBufSizeMax", new(int), func(y interface{}) { x.loadRcvBufSizeMax(y.(int)) }) - m.LoadValue("lastError", new(string), func(y interface{}) { x.loadLastError(y.(string)) }) + m.SaveValue(21, lastError) + m.Save(0, &x.TransportEndpointInfo) + m.Save(1, &x.waiterQueue) + m.Save(2, &x.uniqueID) + m.Save(3, &x.rcvReady) + m.Save(4, &x.rcvList) + m.Save(6, &x.rcvBufSize) + m.Save(7, &x.rcvClosed) + m.Save(8, &x.sndBufSize) + m.Save(9, &x.sndBufSizeMax) + m.Save(10, &x.state) + m.Save(11, &x.dstPort) + m.Save(12, &x.v6only) + m.Save(13, &x.ttl) + m.Save(14, &x.multicastTTL) + m.Save(15, &x.multicastAddr) + m.Save(16, &x.multicastNICID) + m.Save(17, &x.multicastLoop) + m.Save(18, &x.portFlags) + m.Save(19, &x.bindToDevice) + m.Save(20, &x.broadcast) + m.Save(22, &x.boundBindToDevice) + m.Save(23, &x.boundPortFlags) + m.Save(24, &x.sendTOS) + m.Save(25, &x.receiveTOS) + m.Save(26, &x.receiveTClass) + m.Save(27, &x.receiveIPPacketInfo) + m.Save(28, &x.shutdownFlags) + m.Save(29, &x.multicastMemberships) + m.Save(30, &x.effectiveNetProtos) + m.Save(31, &x.owner) +} + +func (x *endpoint) StateLoad(m state.Source) { + m.Load(0, &x.TransportEndpointInfo) + m.Load(1, &x.waiterQueue) + m.Load(2, &x.uniqueID) + m.Load(3, &x.rcvReady) + m.Load(4, &x.rcvList) + m.Load(6, &x.rcvBufSize) + m.Load(7, &x.rcvClosed) + m.Load(8, &x.sndBufSize) + m.Load(9, &x.sndBufSizeMax) + m.Load(10, &x.state) + m.Load(11, &x.dstPort) + m.Load(12, &x.v6only) + m.Load(13, &x.ttl) + m.Load(14, &x.multicastTTL) + m.Load(15, &x.multicastAddr) + m.Load(16, &x.multicastNICID) + m.Load(17, &x.multicastLoop) + m.Load(18, &x.portFlags) + m.Load(19, &x.bindToDevice) + m.Load(20, &x.broadcast) + m.Load(22, &x.boundBindToDevice) + m.Load(23, &x.boundPortFlags) + m.Load(24, &x.sendTOS) + m.Load(25, &x.receiveTOS) + m.Load(26, &x.receiveTClass) + m.Load(27, &x.receiveIPPacketInfo) + m.Load(28, &x.shutdownFlags) + m.Load(29, &x.multicastMemberships) + m.Load(30, &x.effectiveNetProtos) + m.Load(31, &x.owner) + m.LoadValue(5, new(int), func(y interface{}) { x.loadRcvBufSizeMax(y.(int)) }) + m.LoadValue(21, new(string), func(y interface{}) { x.loadLastError(y.(string)) }) m.AfterLoad(x.afterLoad) } +func (x *multicastMembership) StateTypeName() string { + return "pkg/tcpip/transport/udp.multicastMembership" +} + +func (x *multicastMembership) StateFields() []string { + return []string{ + "nicID", + "multicastAddr", + } +} + func (x *multicastMembership) beforeSave() {} -func (x *multicastMembership) save(m state.Map) { + +func (x *multicastMembership) StateSave(m state.Sink) { x.beforeSave() - m.Save("nicID", &x.nicID) - m.Save("multicastAddr", &x.multicastAddr) + m.Save(0, &x.nicID) + m.Save(1, &x.multicastAddr) } func (x *multicastMembership) afterLoad() {} -func (x *multicastMembership) load(m state.Map) { - m.Load("nicID", &x.nicID) - m.Load("multicastAddr", &x.multicastAddr) + +func (x *multicastMembership) StateLoad(m state.Source) { + m.Load(0, &x.nicID) + m.Load(1, &x.multicastAddr) +} + +func (x *udpPacketList) StateTypeName() string { + return "pkg/tcpip/transport/udp.udpPacketList" +} + +func (x *udpPacketList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *udpPacketList) beforeSave() {} -func (x *udpPacketList) save(m state.Map) { + +func (x *udpPacketList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *udpPacketList) afterLoad() {} -func (x *udpPacketList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *udpPacketList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *udpPacketEntry) StateTypeName() string { + return "pkg/tcpip/transport/udp.udpPacketEntry" +} + +func (x *udpPacketEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *udpPacketEntry) beforeSave() {} -func (x *udpPacketEntry) save(m state.Map) { + +func (x *udpPacketEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *udpPacketEntry) afterLoad() {} -func (x *udpPacketEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *udpPacketEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) } func init() { - state.Register("pkg/tcpip/transport/udp.udpPacket", (*udpPacket)(nil), state.Fns{Save: (*udpPacket).save, Load: (*udpPacket).load}) - state.Register("pkg/tcpip/transport/udp.endpoint", (*endpoint)(nil), state.Fns{Save: (*endpoint).save, Load: (*endpoint).load}) - state.Register("pkg/tcpip/transport/udp.multicastMembership", (*multicastMembership)(nil), state.Fns{Save: (*multicastMembership).save, Load: (*multicastMembership).load}) - state.Register("pkg/tcpip/transport/udp.udpPacketList", (*udpPacketList)(nil), state.Fns{Save: (*udpPacketList).save, Load: (*udpPacketList).load}) - state.Register("pkg/tcpip/transport/udp.udpPacketEntry", (*udpPacketEntry)(nil), state.Fns{Save: (*udpPacketEntry).save, Load: (*udpPacketEntry).load}) + state.Register((*udpPacket)(nil)) + state.Register((*endpoint)(nil)) + state.Register((*multicastMembership)(nil)) + state.Register((*udpPacketList)(nil)) + state.Register((*udpPacketEntry)(nil)) } diff --git a/pkg/usermem/usermem_state_autogen.go b/pkg/usermem/usermem_state_autogen.go index 20aa2d2de..d0c854254 100644 --- a/pkg/usermem/usermem_state_autogen.go +++ b/pkg/usermem/usermem_state_autogen.go @@ -6,44 +6,71 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *AccessType) StateTypeName() string { + return "pkg/usermem.AccessType" +} + +func (x *AccessType) StateFields() []string { + return []string{ + "Read", + "Write", + "Execute", + } +} + func (x *AccessType) beforeSave() {} -func (x *AccessType) save(m state.Map) { + +func (x *AccessType) StateSave(m state.Sink) { x.beforeSave() - m.Save("Read", &x.Read) - m.Save("Write", &x.Write) - m.Save("Execute", &x.Execute) + m.Save(0, &x.Read) + m.Save(1, &x.Write) + m.Save(2, &x.Execute) } func (x *AccessType) afterLoad() {} -func (x *AccessType) load(m state.Map) { - m.Load("Read", &x.Read) - m.Load("Write", &x.Write) - m.Load("Execute", &x.Execute) + +func (x *AccessType) StateLoad(m state.Source) { + m.Load(0, &x.Read) + m.Load(1, &x.Write) + m.Load(2, &x.Execute) } -func (x *Addr) save(m state.Map) { - m.SaveValue("", (uintptr)(*x)) +func (x *Addr) StateTypeName() string { + return "pkg/usermem.Addr" } -func (x *Addr) load(m state.Map) { - m.LoadValue("", new(uintptr), func(y interface{}) { *x = (Addr)(y.(uintptr)) }) +func (x *Addr) StateFields() []string { + return nil +} + +func (x *AddrRange) StateTypeName() string { + return "pkg/usermem.AddrRange" +} + +func (x *AddrRange) StateFields() []string { + return []string{ + "Start", + "End", + } } func (x *AddrRange) beforeSave() {} -func (x *AddrRange) save(m state.Map) { + +func (x *AddrRange) StateSave(m state.Sink) { x.beforeSave() - m.Save("Start", &x.Start) - m.Save("End", &x.End) + m.Save(0, &x.Start) + m.Save(1, &x.End) } func (x *AddrRange) afterLoad() {} -func (x *AddrRange) load(m state.Map) { - m.Load("Start", &x.Start) - m.Load("End", &x.End) + +func (x *AddrRange) StateLoad(m state.Source) { + m.Load(0, &x.Start) + m.Load(1, &x.End) } func init() { - state.Register("pkg/usermem.AccessType", (*AccessType)(nil), state.Fns{Save: (*AccessType).save, Load: (*AccessType).load}) - state.Register("pkg/usermem.Addr", (*Addr)(nil), state.Fns{Save: (*Addr).save, Load: (*Addr).load}) - state.Register("pkg/usermem.AddrRange", (*AddrRange)(nil), state.Fns{Save: (*AddrRange).save, Load: (*AddrRange).load}) + state.Register((*AccessType)(nil)) + state.Register((*Addr)(nil)) + state.Register((*AddrRange)(nil)) } diff --git a/pkg/waiter/waiter_list.go b/pkg/waiter/waiter_list.go index 35431f5a4..a91063d9e 100644 --- a/pkg/waiter/waiter_list.go +++ b/pkg/waiter/waiter_list.go @@ -56,7 +56,7 @@ func (l *waiterList) Back() *Entry { // // NOTE: This is an O(n) operation. func (l *waiterList) Len() (count int) { - for e := l.Front(); e != nil; e = e.Next() { + for e := l.Front(); e != nil; e = (waiterElementMapper{}.linkerFor(e)).Next() { count++ } return count @@ -148,13 +148,13 @@ func (l *waiterList) Remove(e *Entry) { if prev != nil { waiterElementMapper{}.linkerFor(prev).SetNext(next) - } else { + } else if l.head == e { l.head = next } if next != nil { waiterElementMapper{}.linkerFor(next).SetPrev(prev) - } else { + } else if l.tail == e { l.tail = prev } diff --git a/pkg/waiter/waiter_state_autogen.go b/pkg/waiter/waiter_state_autogen.go index cf7f5fc2c..086f10dbc 100644 --- a/pkg/waiter/waiter_state_autogen.go +++ b/pkg/waiter/waiter_state_autogen.go @@ -6,64 +6,115 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *Entry) StateTypeName() string { + return "pkg/waiter.Entry" +} + +func (x *Entry) StateFields() []string { + return []string{ + "Context", + "Callback", + "mask", + "waiterEntry", + } +} + func (x *Entry) beforeSave() {} -func (x *Entry) save(m state.Map) { + +func (x *Entry) StateSave(m state.Sink) { x.beforeSave() - m.Save("Context", &x.Context) - m.Save("Callback", &x.Callback) - m.Save("mask", &x.mask) - m.Save("waiterEntry", &x.waiterEntry) + m.Save(0, &x.Context) + m.Save(1, &x.Callback) + m.Save(2, &x.mask) + m.Save(3, &x.waiterEntry) } func (x *Entry) afterLoad() {} -func (x *Entry) load(m state.Map) { - m.Load("Context", &x.Context) - m.Load("Callback", &x.Callback) - m.Load("mask", &x.mask) - m.Load("waiterEntry", &x.waiterEntry) + +func (x *Entry) StateLoad(m state.Source) { + m.Load(0, &x.Context) + m.Load(1, &x.Callback) + m.Load(2, &x.mask) + m.Load(3, &x.waiterEntry) +} + +func (x *Queue) StateTypeName() string { + return "pkg/waiter.Queue" +} + +func (x *Queue) StateFields() []string { + return []string{} } func (x *Queue) beforeSave() {} -func (x *Queue) save(m state.Map) { + +func (x *Queue) StateSave(m state.Sink) { x.beforeSave() if !state.IsZeroValue(&x.list) { - m.Failf("list is %#v, expected zero", &x.list) + state.Failf("list is %#v, expected zero", &x.list) } } func (x *Queue) afterLoad() {} -func (x *Queue) load(m state.Map) { + +func (x *Queue) StateLoad(m state.Source) { +} + +func (x *waiterList) StateTypeName() string { + return "pkg/waiter.waiterList" +} + +func (x *waiterList) StateFields() []string { + return []string{ + "head", + "tail", + } } func (x *waiterList) beforeSave() {} -func (x *waiterList) save(m state.Map) { + +func (x *waiterList) StateSave(m state.Sink) { x.beforeSave() - m.Save("head", &x.head) - m.Save("tail", &x.tail) + m.Save(0, &x.head) + m.Save(1, &x.tail) } func (x *waiterList) afterLoad() {} -func (x *waiterList) load(m state.Map) { - m.Load("head", &x.head) - m.Load("tail", &x.tail) + +func (x *waiterList) StateLoad(m state.Source) { + m.Load(0, &x.head) + m.Load(1, &x.tail) +} + +func (x *waiterEntry) StateTypeName() string { + return "pkg/waiter.waiterEntry" +} + +func (x *waiterEntry) StateFields() []string { + return []string{ + "next", + "prev", + } } func (x *waiterEntry) beforeSave() {} -func (x *waiterEntry) save(m state.Map) { + +func (x *waiterEntry) StateSave(m state.Sink) { x.beforeSave() - m.Save("next", &x.next) - m.Save("prev", &x.prev) + m.Save(0, &x.next) + m.Save(1, &x.prev) } func (x *waiterEntry) afterLoad() {} -func (x *waiterEntry) load(m state.Map) { - m.Load("next", &x.next) - m.Load("prev", &x.prev) + +func (x *waiterEntry) StateLoad(m state.Source) { + m.Load(0, &x.next) + m.Load(1, &x.prev) } func init() { - state.Register("pkg/waiter.Entry", (*Entry)(nil), state.Fns{Save: (*Entry).save, Load: (*Entry).load}) - state.Register("pkg/waiter.Queue", (*Queue)(nil), state.Fns{Save: (*Queue).save, Load: (*Queue).load}) - state.Register("pkg/waiter.waiterList", (*waiterList)(nil), state.Fns{Save: (*waiterList).save, Load: (*waiterList).load}) - state.Register("pkg/waiter.waiterEntry", (*waiterEntry)(nil), state.Fns{Save: (*waiterEntry).save, Load: (*waiterEntry).load}) + state.Register((*Entry)(nil)) + state.Register((*Queue)(nil)) + state.Register((*waiterList)(nil)) + state.Register((*waiterEntry)(nil)) } diff --git a/runsc/boot/boot_state_autogen.go b/runsc/boot/boot_state_autogen.go index 167d1cf02..d025a2a1a 100644 --- a/runsc/boot/boot_state_autogen.go +++ b/runsc/boot/boot_state_autogen.go @@ -6,19 +6,32 @@ import ( "gvisor.dev/gvisor/pkg/state" ) +func (x *sandboxNetstackCreator) StateTypeName() string { + return "runsc/boot.sandboxNetstackCreator" +} + +func (x *sandboxNetstackCreator) StateFields() []string { + return []string{ + "clock", + "uniqueID", + } +} + func (x *sandboxNetstackCreator) beforeSave() {} -func (x *sandboxNetstackCreator) save(m state.Map) { + +func (x *sandboxNetstackCreator) StateSave(m state.Sink) { x.beforeSave() - m.Save("clock", &x.clock) - m.Save("uniqueID", &x.uniqueID) + m.Save(0, &x.clock) + m.Save(1, &x.uniqueID) } func (x *sandboxNetstackCreator) afterLoad() {} -func (x *sandboxNetstackCreator) load(m state.Map) { - m.Load("clock", &x.clock) - m.Load("uniqueID", &x.uniqueID) + +func (x *sandboxNetstackCreator) StateLoad(m state.Source) { + m.Load(0, &x.clock) + m.Load(1, &x.uniqueID) } func init() { - state.Register("runsc/boot.sandboxNetstackCreator", (*sandboxNetstackCreator)(nil), state.Fns{Save: (*sandboxNetstackCreator).save, Load: (*sandboxNetstackCreator).load}) + state.Register((*sandboxNetstackCreator)(nil)) } diff --git a/runsc/cmd/statefile.go b/runsc/cmd/statefile.go index e6f1907da..daed9e728 100644 --- a/runsc/cmd/statefile.go +++ b/runsc/cmd/statefile.go @@ -20,7 +20,7 @@ import ( "os" "github.com/google/subcommands" - "gvisor.dev/gvisor/pkg/state" + "gvisor.dev/gvisor/pkg/state/pretty" "gvisor.dev/gvisor/pkg/state/statefile" "gvisor.dev/gvisor/runsc/flag" ) @@ -105,8 +105,14 @@ func (s *Statefile) Execute(_ context.Context, f *flag.FlagSet, args ...interfac if err != nil { Fatalf("error parsing statefile: %v", err) } - if err := state.PrettyPrint(output, rc, s.html); err != nil { - Fatalf("error printing state: %v", err) + if s.html { + if err := pretty.PrintHTML(output, rc); err != nil { + Fatalf("error printing state: %v", err) + } + } else { + if err := pretty.PrintText(output, rc); err != nil { + Fatalf("error printing state: %v", err) + } } return subcommands.ExitSuccess } |