MCPcopy
hub / github.com/containerd/containerd / stopContainer

Method stopContainer

internal/cri/server/container_stop.go:111–249  ·  view source on GitHub ↗

stopContainer stops a container based on the container metadata.

(ctx context.Context, container containerstore.Container, timeout time.Duration)

Source from the content-addressed store, hash-verified

109
110// stopContainer stops a container based on the container metadata.
111func (c *criService) stopContainer(ctx context.Context, container containerstore.Container, timeout time.Duration) error {
112 span := tracing.SpanFromContext(ctx)
113 start := time.Now()
114 id := container.ID
115 sandboxID := container.SandboxID
116
117 // Return without error if container is not running. This makes sure that
118 // stop only takes real action after the container is started.
119 state := container.Status.Get().State()
120 if state != runtime.ContainerState_CONTAINER_RUNNING &&
121 state != runtime.ContainerState_CONTAINER_UNKNOWN {
122 log.G(ctx).Infof("Container to stop %q must be in running or unknown state, current state %q",
123 id, criContainerStateToString(state))
124 return nil
125 }
126
127 task, err := container.Container.Task(ctx, nil)
128 if err != nil {
129 if !errdefs.IsNotFound(err) {
130 return fmt.Errorf("failed to get task for container %q: %w", id, err)
131 }
132 // Don't return for unknown state, some cleanup needs to be done.
133 if state == runtime.ContainerState_CONTAINER_UNKNOWN {
134 return c.cleanupUnknownContainer(ctx, id, container, sandboxID)
135 }
136 return nil
137 }
138
139 // Handle unknown state.
140 if state == runtime.ContainerState_CONTAINER_UNKNOWN {
141 // Start an exit handler for containers in unknown state.
142 waitCtx, waitCancel := context.WithCancel(ctrdutil.NamespacedContext())
143 defer waitCancel()
144 exitCh, err := task.Wait(waitCtx)
145 if err != nil {
146 if !errdefs.IsNotFound(err) {
147 return fmt.Errorf("failed to wait for task for %q: %w", id, err)
148 }
149 return c.cleanupUnknownContainer(ctx, id, container, sandboxID)
150 }
151
152 exitCtx, exitCancel := context.WithCancel(context.Background())
153 stopCh := c.startContainerExitMonitor(exitCtx, id, task.Pid(), exitCh)
154 defer func() {
155 exitCancel()
156 // This ensures that exit monitor is stopped before
157 // `Wait` is cancelled, so no exit event is generated
158 // because of the `Wait` cancellation.
159 <-stopCh
160 }()
161 }
162
163 // We only need to kill the task. The event handler will Delete the
164 // task from containerd after it handles the Exited event.
165 if timeout > 0 {
166 stopSignal := "SIGTERM"
167 if signal := container.Config.GetStopSignal(); signal != runtime.Signal_RUNTIME_DEFAULT {
168 stopSignal, err = criSignalToOCIStopSignal(signal)

Implementers 1

criServiceinternal/cri/server/service.go

Calls 15

waitContainerStopMethod · 0.95
SpanFromContextFunction · 0.92
AttributeFunction · 0.92
criSignalToOCIStopSignalFunction · 0.85
AddEventMethod · 0.80
StateMethod · 0.65
GetMethod · 0.65
TaskMethod · 0.65
WaitMethod · 0.65

Tested by

no test coverage detected