diff --git a/internal/oci/container.go b/internal/oci/container.go index 559c8f8c9a7..c86707cffcf 100644 --- a/internal/oci/container.go +++ b/internal/oci/container.go @@ -553,7 +553,10 @@ func (c *Container) Spoofed() bool { // If a stop is currently happening, it also sends the new timeout // along the stopTimeoutChan, allowing the in-progress stop // to stop faster, or ignore the new stop timeout. -func (c *Container) SetAsStopping(timeout int64) { +// In this case, it also returns true, signifying the caller doesn't have to +// Do any stop related cleanup, as the original caller (alreadyStopping=false) +// will do said cleanup. +func (c *Container) SetAsStopping(timeout int64) (alreadyStopping bool) { // First, need to check if the container is already stopping c.stopLock.Lock() defer c.stopLock.Unlock() @@ -567,12 +570,13 @@ func (c *Container) SetAsStopping(timeout int64) { case <-c.stoppedChan: // This case is to avoid waiting forever once another routine has finished. case <-c.stopStoppingChan: // This case is to avoid deadlocking with SetAsNotStopping. } - return + return true } // Regardless, set the container as actively stopping. c.stopping = true // And reset the stopStoppingChan c.stopStoppingChan = make(chan struct{}, 1) + return false } // SetAsNotStopping unsets the stopping field indicating to new callers that the container diff --git a/internal/oci/runtime_oci.go b/internal/oci/runtime_oci.go index 6295ff9acae..08a7a6eb13b 100644 --- a/internal/oci/runtime_oci.go +++ b/internal/oci/runtime_oci.go @@ -692,7 +692,9 @@ func WaitContainerStop(ctx context.Context, c *Container, timeout time.Duration, // StopContainer stops a container. Timeout is given in seconds. func (r *runtimeOCI) StopContainer(ctx context.Context, c *Container, timeout int64) (retErr error) { - c.SetAsStopping(timeout) + if c.SetAsStopping(timeout) { + return nil + } defer func() { if retErr != nil { // Failed to stop, set stopping to false. diff --git a/test/ctr.bats b/test/ctr.bats index 3e7577dac9f..74c9a14d737 100644 --- a/test/ctr.bats +++ b/test/ctr.bats @@ -926,3 +926,16 @@ function check_oci_annotation() { pod_id=$(crictl runp "$TESTDATA"/sandbox_config.json) ! crictl create "$pod_id" "$TESTDIR/config" "$TESTDATA"/sandbox_config.json } + +@test "ctr stop timeouts should decrease" { + start_crio + jq ' .command'='["/bin/sh", "-c", "trap \"echo hi\" INT; /bin/sleep 6000"]' \ + "$TESTDATA"/container_config.json > "$newconfig" + + ctr_id=$(crictl run "$newconfig" "$TESTDATA"/sandbox_config.json) + for i in {150..1}; do + crictl stop --timeout "$i" "$ctr_id" & + sleep .1 + done + crictl stop "$ctr_id" +}