Skip to content

Commit f5e7fe0

Browse files
authored
Merge pull request containerd#9644 from abel-von/fix-sandbox-status
sandbox: fix podsandbox recover status issue
2 parents 0125a42 + e230ed9 commit f5e7fe0

File tree

3 files changed

+506
-4
lines changed

3 files changed

+506
-4
lines changed

integration/restart_linux_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
Copyright The containerd Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package integration
18+
19+
import (
20+
"syscall"
21+
"testing"
22+
"time"
23+
24+
"github.com/stretchr/testify/assert"
25+
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
26+
)
27+
28+
func TestContainerdRestartSandboxRecover(t *testing.T) {
29+
sbStatuses := map[string]runtime.PodSandboxState{
30+
// Sandbox with unknown status will be NotReady when returned from ListPodSandbox
31+
"sandbox_unknown": runtime.PodSandboxState_SANDBOX_NOTREADY,
32+
"sandbox_not_ready": runtime.PodSandboxState_SANDBOX_NOTREADY,
33+
"sandbox_ready": runtime.PodSandboxState_SANDBOX_READY,
34+
}
35+
36+
sbReadyConfig := PodSandboxConfig("sandbox_ready", "sandbox_ready")
37+
_, err := runtimeService.RunPodSandbox(sbReadyConfig, *runtimeHandler)
38+
assert.NoError(t, err)
39+
40+
sbNotReadyConfig := PodSandboxConfig("sandbox_not_ready", "sandbox_not_ready")
41+
notReadyID, err := runtimeService.RunPodSandbox(sbNotReadyConfig, *runtimeHandler)
42+
assert.NoError(t, err)
43+
err = runtimeService.StopPodSandbox(notReadyID)
44+
assert.NoError(t, err)
45+
46+
t.Logf("Create a pod config with shim create delay")
47+
sbUnknownConfig := PodSandboxConfig("sandbox_unknown", "sandbox_unknown_status")
48+
injectShimFailpoint(t, sbUnknownConfig, map[string]string{
49+
"Create": "1*delay(2000)",
50+
})
51+
waitCh := make(chan struct{})
52+
go func() {
53+
time.Sleep(time.Second)
54+
t.Logf("Create a sandbox with shim create delay")
55+
RestartContainerd(t, syscall.SIGTERM)
56+
waitCh <- struct{}{}
57+
}()
58+
t.Logf("Create a sandbox with shim create delay")
59+
_, err = runtimeService.RunPodSandbox(sbUnknownConfig, failpointRuntimeHandler)
60+
assert.Error(t, err)
61+
<-waitCh
62+
sbs, err := runtimeService.ListPodSandbox(nil)
63+
assert.NoError(t, err)
64+
foundUnkownSb := false
65+
for _, sb := range sbs {
66+
if sb.Metadata.Name == "sandbox_unknown" {
67+
foundUnkownSb = true
68+
}
69+
if status, ok := sbStatuses[sb.Metadata.Name]; ok {
70+
assert.Equal(t, status, sb.State)
71+
err = runtimeService.StopPodSandbox(sb.Id)
72+
assert.NoError(t, err)
73+
err = runtimeService.RemovePodSandbox(sb.Id)
74+
assert.NoError(t, err)
75+
}
76+
}
77+
assert.True(t, foundUnkownSb)
78+
}

internal/cri/server/podsandbox/recover.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,17 @@ func (c *Controller) RecoverContainer(ctx context.Context, cntr containerd.Conta
9696
status.State = sandboxstore.StateNotReady
9797
} else {
9898
if taskStatus.Status == containerd.Running {
99-
status.State = sandboxstore.StateReady
100-
status.Pid = t.Pid()
10199
exitCh, err := t.Wait(ctrdutil.NamespacedContext())
102100
if err != nil {
103-
return status, channel, fmt.Errorf("failed to wait for sandbox container task: %w", err)
101+
if !errdefs.IsNotFound(err) {
102+
return status, channel, fmt.Errorf("failed to wait for sandbox container task: %w", err)
103+
}
104+
status.State = sandboxstore.StateNotReady
105+
} else {
106+
status.State = sandboxstore.StateReady
107+
status.Pid = t.Pid()
108+
channel = exitCh
104109
}
105-
channel = exitCh
106110
} else {
107111
// Task is not running. Delete the task and set sandbox state as NOTREADY.
108112
if _, err := t.Delete(ctx, containerd.WithProcessKill); err != nil && !errdefs.IsNotFound(err) {

0 commit comments

Comments
 (0)