Skip to content

Commit c8c41e5

Browse files
fvoznikagvisor-bot
authored andcommitted
Move S/R code to separate file
Move Kernel S/R code to kernel_restore.go. PiperOrigin-RevId: 691441815
1 parent 7b3216a commit c8c41e5

File tree

3 files changed

+120
-104
lines changed

3 files changed

+120
-104
lines changed

pkg/sentry/kernel/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ go_library(
252252
"kcov_unsafe.go",
253253
"kernel.go",
254254
"kernel_opts.go",
255+
"kernel_restore.go",
255256
"kernel_state.go",
256257
"pending_signals.go",
257258
"pending_signals_list.go",

pkg/sentry/kernel/kernel.go

Lines changed: 0 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -393,12 +393,6 @@ type Kernel struct {
393393
UnixSocketOpts transport.UnixSocketOpts
394394
}
395395

396-
// Saver is an interface for saving the kernel.
397-
type Saver interface {
398-
SaveAsync() error
399-
SpecEnviron(containerName string) []string
400-
}
401-
402396
// InitKernelArgs holds arguments to Init.
403397
type InitKernelArgs struct {
404398
// FeatureSet is the emulated CPU feature set.
@@ -1921,28 +1915,6 @@ func (k *Kernel) SetHostMount(mnt *vfs.Mount) {
19211915
k.hostMount = mnt
19221916
}
19231917

1924-
// AddStateToCheckpoint adds a key-value pair to be additionally checkpointed.
1925-
func (k *Kernel) AddStateToCheckpoint(key, v any) {
1926-
k.checkpointMu.Lock()
1927-
defer k.checkpointMu.Unlock()
1928-
if k.additionalCheckpointState == nil {
1929-
k.additionalCheckpointState = make(map[any]any)
1930-
}
1931-
k.additionalCheckpointState[key] = v
1932-
}
1933-
1934-
// PopCheckpointState pops a key-value pair from the additional checkpoint
1935-
// state. If the key doesn't exist, nil is returned.
1936-
func (k *Kernel) PopCheckpointState(key any) any {
1937-
k.checkpointMu.Lock()
1938-
defer k.checkpointMu.Unlock()
1939-
if v, ok := k.additionalCheckpointState[key]; ok {
1940-
delete(k.additionalCheckpointState, key)
1941-
return v
1942-
}
1943-
return nil
1944-
}
1945-
19461918
// HostMount returns the hostfs mount.
19471919
func (k *Kernel) HostMount() *vfs.Mount {
19481920
return k.hostMount
@@ -2202,79 +2174,3 @@ func (k *Kernel) ContainerName(cid string) string {
22022174
defer k.extMu.Unlock()
22032175
return k.containerNames[cid]
22042176
}
2205-
2206-
// SetSaver sets the kernel's Saver.
2207-
// Thread-compatible.
2208-
func (k *Kernel) SetSaver(s Saver) {
2209-
k.checkpointMu.Lock()
2210-
defer k.checkpointMu.Unlock()
2211-
k.saver = s
2212-
}
2213-
2214-
// Saver returns the kernel's Saver.
2215-
// Thread-compatible.
2216-
func (k *Kernel) Saver() Saver {
2217-
k.checkpointMu.Lock()
2218-
defer k.checkpointMu.Unlock()
2219-
return k.saver
2220-
}
2221-
2222-
// IncCheckpointCount increments the checkpoint counter.
2223-
func (k *Kernel) IncCheckpointCount() {
2224-
k.checkpointMu.Lock()
2225-
defer k.checkpointMu.Unlock()
2226-
k.checkpointCounter++
2227-
}
2228-
2229-
// CheckpointCount returns the current checkpoint count. Note that the result
2230-
// may be stale by the time the caller uses it.
2231-
func (k *Kernel) CheckpointCount() uint32 {
2232-
k.checkpointMu.Lock()
2233-
defer k.checkpointMu.Unlock()
2234-
return k.checkpointCounter
2235-
}
2236-
2237-
// OnCheckpointAttempt is called when a checkpoint attempt is completed. err is
2238-
// any checkpoint errors that may have occurred.
2239-
func (k *Kernel) OnCheckpointAttempt(err error) {
2240-
k.checkpointMu.Lock()
2241-
defer k.checkpointMu.Unlock()
2242-
if err == nil {
2243-
k.checkpointCounter++
2244-
}
2245-
k.lastCheckpointStatus = err
2246-
k.checkpointCond.Broadcast()
2247-
}
2248-
2249-
// ResetCheckpointStatus resets the last checkpoint status, indicating a new
2250-
// checkpoint is in progress. Caller must call OnCheckpointAttempt when the
2251-
// checkpoint attempt is completed.
2252-
func (k *Kernel) ResetCheckpointStatus() {
2253-
k.checkpointMu.Lock()
2254-
defer k.checkpointMu.Unlock()
2255-
k.lastCheckpointStatus = nil
2256-
}
2257-
2258-
// WaitCheckpoint waits for the Kernel to have been successfully checkpointed
2259-
// n-1 times, then waits for either the n-th successful checkpoint (in which
2260-
// case it returns nil) or any number of failed checkpoints (in which case it
2261-
// returns an error returned by any such failure).
2262-
func (k *Kernel) WaitCheckpoint(n uint32) error {
2263-
if n == 0 {
2264-
return nil
2265-
}
2266-
k.checkpointMu.Lock()
2267-
defer k.checkpointMu.Unlock()
2268-
if k.checkpointCounter >= n {
2269-
// n-th checkpoint already completed successfully.
2270-
return nil
2271-
}
2272-
for k.checkpointCounter < n {
2273-
if k.checkpointCounter == n-1 && k.lastCheckpointStatus != nil {
2274-
// n-th checkpoint was attempted but it had failed.
2275-
return k.lastCheckpointStatus
2276-
}
2277-
k.checkpointCond.Wait()
2278-
}
2279-
return nil
2280-
}

pkg/sentry/kernel/kernel_restore.go

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Copyright 2024 The gVisor Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package kernel
16+
17+
// Saver is an interface for saving the kernel.
18+
type Saver interface {
19+
SaveAsync() error
20+
SpecEnviron(containerName string) []string
21+
}
22+
23+
// AddStateToCheckpoint adds a key-value pair to be additionally checkpointed.
24+
func (k *Kernel) AddStateToCheckpoint(key, v any) {
25+
k.checkpointMu.Lock()
26+
defer k.checkpointMu.Unlock()
27+
if k.additionalCheckpointState == nil {
28+
k.additionalCheckpointState = make(map[any]any)
29+
}
30+
k.additionalCheckpointState[key] = v
31+
}
32+
33+
// PopCheckpointState pops a key-value pair from the additional checkpoint
34+
// state. If the key doesn't exist, nil is returned.
35+
func (k *Kernel) PopCheckpointState(key any) any {
36+
k.checkpointMu.Lock()
37+
defer k.checkpointMu.Unlock()
38+
if v, ok := k.additionalCheckpointState[key]; ok {
39+
delete(k.additionalCheckpointState, key)
40+
return v
41+
}
42+
return nil
43+
}
44+
45+
// SetSaver sets the kernel's Saver.
46+
// Thread-compatible.
47+
func (k *Kernel) SetSaver(s Saver) {
48+
k.checkpointMu.Lock()
49+
defer k.checkpointMu.Unlock()
50+
k.saver = s
51+
}
52+
53+
// Saver returns the kernel's Saver.
54+
// Thread-compatible.
55+
func (k *Kernel) Saver() Saver {
56+
k.checkpointMu.Lock()
57+
defer k.checkpointMu.Unlock()
58+
return k.saver
59+
}
60+
61+
// IncCheckpointCount increments the checkpoint counter.
62+
func (k *Kernel) IncCheckpointCount() {
63+
k.checkpointMu.Lock()
64+
defer k.checkpointMu.Unlock()
65+
k.checkpointCounter++
66+
}
67+
68+
// CheckpointCount returns the current checkpoint count. Note that the result
69+
// may be stale by the time the caller uses it.
70+
func (k *Kernel) CheckpointCount() uint32 {
71+
k.checkpointMu.Lock()
72+
defer k.checkpointMu.Unlock()
73+
return k.checkpointCounter
74+
}
75+
76+
// OnCheckpointAttempt is called when a checkpoint attempt is completed. err is
77+
// any checkpoint errors that may have occurred.
78+
func (k *Kernel) OnCheckpointAttempt(err error) {
79+
k.checkpointMu.Lock()
80+
defer k.checkpointMu.Unlock()
81+
if err == nil {
82+
k.checkpointCounter++
83+
}
84+
k.lastCheckpointStatus = err
85+
k.checkpointCond.Broadcast()
86+
}
87+
88+
// ResetCheckpointStatus resets the last checkpoint status, indicating a new
89+
// checkpoint is in progress. Caller must call OnCheckpointAttempt when the
90+
// checkpoint attempt is completed.
91+
func (k *Kernel) ResetCheckpointStatus() {
92+
k.checkpointMu.Lock()
93+
defer k.checkpointMu.Unlock()
94+
k.lastCheckpointStatus = nil
95+
}
96+
97+
// WaitCheckpoint waits for the Kernel to have been successfully checkpointed
98+
// n-1 times, then waits for either the n-th successful checkpoint (in which
99+
// case it returns nil) or any number of failed checkpoints (in which case it
100+
// returns an error returned by any such failure).
101+
func (k *Kernel) WaitCheckpoint(n uint32) error {
102+
if n == 0 {
103+
return nil
104+
}
105+
k.checkpointMu.Lock()
106+
defer k.checkpointMu.Unlock()
107+
if k.checkpointCounter >= n {
108+
// n-th checkpoint already completed successfully.
109+
return nil
110+
}
111+
for k.checkpointCounter < n {
112+
if k.checkpointCounter == n-1 && k.lastCheckpointStatus != nil {
113+
// n-th checkpoint was attempted but it had failed.
114+
return k.lastCheckpointStatus
115+
}
116+
k.checkpointCond.Wait()
117+
}
118+
return nil
119+
}

0 commit comments

Comments
 (0)