X Tutup
Skip to content

Commit b554b57

Browse files
committed
Move shim restore to a separate file
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
1 parent a3d2981 commit b554b57

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

runtime/v2/shim_load.go

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
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 v2
18+
19+
import (
20+
"context"
21+
"os"
22+
"path/filepath"
23+
24+
"github.com/containerd/containerd/containers"
25+
"github.com/containerd/containerd/events/exchange"
26+
"github.com/containerd/containerd/log"
27+
"github.com/containerd/containerd/mount"
28+
"github.com/containerd/containerd/namespaces"
29+
"github.com/containerd/containerd/plugin"
30+
"github.com/containerd/containerd/runtime"
31+
)
32+
33+
func loadExistingTasks(ic *plugin.InitContext, list *runtime.TaskList, events *exchange.Exchange, containers containers.Store) error {
34+
var (
35+
ctx = ic.Context
36+
state = ic.State
37+
root = ic.Root
38+
containerdAddress = ic.Address
39+
containerdTTRPCAddress = ic.TTRPCAddress
40+
)
41+
42+
nsDirs, err := os.ReadDir(state)
43+
if err != nil {
44+
return err
45+
}
46+
for _, nsd := range nsDirs {
47+
if !nsd.IsDir() {
48+
continue
49+
}
50+
ns := nsd.Name()
51+
// skip hidden directories
52+
if len(ns) > 0 && ns[0] == '.' {
53+
continue
54+
}
55+
log.G(ctx).WithField("namespace", ns).Debug("loading tasks in namespace")
56+
if err := loadShims(namespaces.WithNamespace(ctx, ns), state, list, events, containers, containerdAddress, containerdTTRPCAddress); err != nil {
57+
log.G(ctx).WithField("namespace", ns).WithError(err).Error("loading tasks in namespace")
58+
continue
59+
}
60+
if err := cleanupWorkDirs(namespaces.WithNamespace(ctx, ns), root, list); err != nil {
61+
log.G(ctx).WithField("namespace", ns).WithError(err).Error("cleanup working directory in namespace")
62+
continue
63+
}
64+
}
65+
66+
return nil
67+
}
68+
69+
func loadShims(ctx context.Context, state string, list *runtime.TaskList, events *exchange.Exchange, containers containers.Store, containerdAddress string, containerdTTRPCAddress string) error {
70+
ns, err := namespaces.NamespaceRequired(ctx)
71+
if err != nil {
72+
return err
73+
}
74+
shimDirs, err := os.ReadDir(filepath.Join(state, ns))
75+
if err != nil {
76+
return err
77+
}
78+
for _, sd := range shimDirs {
79+
if !sd.IsDir() {
80+
continue
81+
}
82+
id := sd.Name()
83+
// skip hidden directories
84+
if len(id) > 0 && id[0] == '.' {
85+
continue
86+
}
87+
bundle, err := LoadBundle(ctx, state, id)
88+
if err != nil {
89+
// fine to return error here, it is a programmer error if the context
90+
// does not have a namespace
91+
return err
92+
}
93+
// fast path
94+
bf, err := os.ReadDir(bundle.Path)
95+
if err != nil {
96+
bundle.Delete()
97+
log.G(ctx).WithError(err).Errorf("fast path read bundle path for %s", bundle.Path)
98+
continue
99+
}
100+
if len(bf) == 0 {
101+
bundle.Delete()
102+
continue
103+
}
104+
container, err := containers.Get(ctx, id)
105+
if err != nil {
106+
log.G(ctx).WithError(err).Errorf("loading container %s", id)
107+
if err := mount.UnmountAll(filepath.Join(bundle.Path, "rootfs"), 0); err != nil {
108+
log.G(ctx).WithError(err).Errorf("forceful unmount of rootfs %s", id)
109+
}
110+
bundle.Delete()
111+
continue
112+
}
113+
binaryCall := shimBinary(bundle, container.Runtime.Name, containerdAddress, containerdTTRPCAddress)
114+
shim, err := loadShim(ctx, bundle, func() {
115+
log.G(ctx).WithField("id", id).Info("shim disconnected")
116+
117+
cleanupAfterDeadShim(context.Background(), id, ns, list, events, binaryCall)
118+
// Remove self from the runtime task list.
119+
list.Delete(ctx, id)
120+
})
121+
if err != nil {
122+
cleanupAfterDeadShim(ctx, id, ns, list, events, binaryCall)
123+
continue
124+
}
125+
list.Add(ctx, shim)
126+
}
127+
return nil
128+
}
129+
130+
func cleanupWorkDirs(ctx context.Context, root string, list *runtime.TaskList) error {
131+
ns, err := namespaces.NamespaceRequired(ctx)
132+
if err != nil {
133+
return err
134+
}
135+
dirs, err := os.ReadDir(filepath.Join(root, ns))
136+
if err != nil {
137+
return err
138+
}
139+
for _, d := range dirs {
140+
// if the task was not loaded, cleanup and empty working directory
141+
// this can happen on a reboot where /run for the bundle state is cleaned up
142+
// but that persistent working dir is left
143+
if _, err := list.Get(ctx, d.Name()); err != nil {
144+
path := filepath.Join(root, ns, d.Name())
145+
if err := os.RemoveAll(path); err != nil {
146+
log.G(ctx).WithError(err).Errorf("cleanup working dir %s", path)
147+
}
148+
}
149+
}
150+
return nil
151+
}

0 commit comments

Comments
 (0)
X Tutup