Andy Huang created YUNIKORN-3404:
------------------------------------

             Summary: PlaceholderManager Start and Stop operations have race 
conditions
                 Key: YUNIKORN-3404
                 URL: https://issues.apache.org/jira/browse/YUNIKORN-3404
             Project: Apache YuniKorn
          Issue Type: Bug
          Components: shim - kubernetes
            Reporter: Andy Huang


The Kubernetes shim PlaceholderManager lifecycle implementation has several 
race conditions around its running state and stop channel.

PlaceholderManager.Start() currently checks the running atomic and updates it 
in two separate operations:

{code:go}
if mgr.isRunning() {
    return
}
mgr.setRunning(true)
go func() {
    // ...
}()
{code}

Concurrent Start() calls can both observe running=false before either call 
stores true. This may start multiple cleanup goroutines for the same 
PlaceholderManager.

PlaceholderManager.Stop() has a similar check-then-act pattern:

{code:go}
if !mgr.isRunning() {
    return
}
mgr.stopChan <- struct{}{}
{code}

Concurrent Stop() calls can both observe running=true. Only one send can be 
received before the cleanup goroutine exits, potentially leaving another caller 
blocked indefinitely on the unbuffered stop channel.

The running state is changed asynchronously by the cleanup goroutine after 
receiving the stop signal. Stop() therefore does not guarantee that the manager 
is fully stopped when it returns, and lifecycle state can become inconsistent 
when Start() and Stop() are invoked concurrently.

The lifecycle operations should be made atomic and idempotent. Possible 
approaches include CompareAndSwap for state transitions, closing a stop channel 
exactly once, and waiting for the cleanup goroutine to exit.

This was identified while reviewing the KubernetesShim shutdown fixes in:

* YUNIKORN-3367
* YUNIKORN-3368
* https://github.com/apache/yunikorn-k8shim/pull/1074

Relevant code:

* pkg/cache/placeholder_manager.go
* PlaceholderManager.Start()
* PlaceholderManager.Stop()
{code}

**Expected behavior**

```text
* At most one PlaceholderManager cleanup goroutine can run.
* Concurrent Start() calls do not start duplicate goroutines.
* Stop() is safe and idempotent.
* Concurrent Stop() calls do not block or panic.
* When Stop() returns, the manager has either fully stopped or exposes a 
reliable way to wait for shutdown completion.
* Start() and Stop() do not leave the running state inconsistent.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to