Devesh Kumar Singh created HDDS-16504:
-----------------------------------------

             Summary: Datanode startup can hang indefinitely when Ratis group 
recovery stalls (add a timeout/watchdog around container initialization)
                 Key: HDDS-16504
                 URL: https://issues.apache.org/jira/browse/HDDS-16504
             Project: Apache Ozone
          Issue Type: Improvement
          Components: Ozone Datanode
            Reporter: Devesh Kumar Singh


[HDDS-16425|https://issues.apache.org/jira/browse/HDDS-16425] makes datanode 
startup fail cleanly when container initialization throws (e.g., a corrupt Raft 
log with raft.server.log.corruption.policy = EXCEPTION): the state is marked 
FAILED, waiting callers fail fast, and the datanode shuts down.

However, it does not cover the case where initialization hangs without 
throwing. If OzoneContainer.start() → writeChannel.start() → 
XceiverServerRatis.start() → Ratis server.start() blocks while recovering a 
Raft group — for example a slow or failing volume where a disk read never 
returns — then:

initializeContainerServices(...) never returns, so the thread holding 
initializationLock holds it indefinitely.
OzoneContainer.start() never reaches INITIALIZED or FAILED.
VersionEndpointTask never advances the endpoint past GETVERSION, so the 
datanode never registers or heartbeats.
RunningDatanodeState logs an endpoint‑task timeout every heartbeat interval, 
forever, with no forward progress and no clean shutdown.
Net effect: the datanode is a "zombie" — the process is up but never registers, 
and (unlike the throw path) it neither recovers nor fails cleanly. Only an 
external restart clears it, and on restart the same group recovery is attempted 
again, reproducing the hang.

*Current behavior*

* Throw during init → handled by HDDS‑16425 (FAILED + clean shutdown). 
* Indefinite block during init (I/O stall in group recovery) → infinite hold of 
initializationLock, no FAILED, no shutdown. 
*Proposed change*

Add a bounded timeout/watchdog around container initialization so a stalled 
startup is converted into an initialization failure that reuses the HDDS‑16425 
clean‑shutdown path:

* Run initializeContainerServices(...) (or at minimum the writeChannel.start() 
group‑recovery step) with a configurable timeout.
* If it does not complete within the timeout, mark initializingStatus = FAILED, 
record a descriptive cause (e.g., TimeoutException("Container initialization 
did not complete within <N>s")), release waiting callers with that failure, and 
trigger the datanode shutdown path — the same terminal outcome as a thrown 
initialization error.
* Because a thread blocked in a native/disk read generally cannot be 
interrupted reliably, the watchdog should not depend on unblocking the stuck 
thread; marking FAILED and initiating shutdown is sufficient (the process will 
terminate).

*Configuration*

New config key (e.g., hdds.datanode.container.init.timeout) with a generous 
default (group recovery on large logs can legitimately take time; the goal is 
to catch true stalls, not slow‑but‑healthy startups). Timeout of 0/negative 
disables the watchdog (preserves current behavior).



--
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