Skip to content

fix: hold startMx on the start path actually exercised - #14106

Merged
ndeloof merged 1 commit into
mainfrom
c1-startmx-real-path
Aug 20, 2026
Merged

fix: hold startMx on the start path actually exercised#14106
ndeloof merged 1 commit into
mainfrom
c1-startmx-real-path

Conversation

@ndeloof

@ndeloofndeloof commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

startMx exists to serialize ContainerStart because the engine assigns published ports from ranges non-atomically — but it is only held by the plan executor's execStartContainer, a nearly dead path (plans emit OpStartContainer only for paused/dead containers). startServiceContainer, the path every up/start actually runs, never takes it: the protection is inoperative today.

This takes the mutex around the real ContainerStart call and documents the contract. Trade-off worth an explicit maintainer call (also raised in #14081): this serializes the start API call across services (replicas were already sequential). The alternative is deleting startMx entirely — happy to flip this PR that way instead. Engine-side references to inform that call: startMx was introduced by #12851 as a workaround for #12846 (duplicate host ports on random-port mappings); there is no dedicated moby issue, but moby/moby#50054 (merged, ships in Engine 28.3.0) explicitly fixes#12846 — a daemon port-allocator flaw (SO_REUSEADDR hid 0.0.0.0 vs specific-address clashes from bind()), introduced by the 28.0 port-mapping refactor (moby/moby#48567/#48132). Notably @robmry assessed on #12846 that the original problem was not a race between container starts, so the mutex likely never protected against that case; engines 28.0–28.2 remain exposed to it either way.

Part of #14074 (section C) — lot 0 of #14081.

🤖 Generated with Claude Code

startMx exists to serialize ContainerStart calls because the engine
assigns published ports from ranges non-atomically. It is held by the
plan executor's execStartContainer — a nearly dead code path (plans
only emit OpStartContainer for paused/dead containers) — and NOT by
startServiceContainer, the path every up/start actually runs. The
protection is thus inoperative today: concurrent services publishing
overlapping port ranges can race in the engine.
Take the mutex around the real ContainerStart call and document the
contract on the variable. Starts of different services were already
serialized per-service (replicas start sequentially); this serializes
the API call across services too, matching what the plan engine will
do once the start phase converges (#14081).
Part of #14074 (section C) / #14081 (lot 0).
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
@ndeloof
ndeloof merged commit b857135 into mainAug 20, 2026
132 of 135 checks passed
@ndeloof
ndeloof deleted the c1-startmx-real-path branch August 20, 2026 13:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] docker engine and desktop expose random ports differently

2 participants

@ndeloof@glours