Skip to content

[WSLC] (2/4) Hold multiple sessions in the lifecycle daemon - #1489

Open
Soham Das (SohamDas2021) wants to merge 5 commits into
mainfrom
sohamdas2021-pr2-multi-session-daemon
Open

Soham Das (SohamDas2021) wants to merge 5 commits into
mainfrom
sohamdas2021-pr2-multi-session-daemon

Conversation

@SohamDas2021

@SohamDas2021 Soham Das (SohamDas2021) commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

📖 Description

The container-lifecycle daemon held exactly one WSLc session — one WSL2 utility VM — and created every sandbox's container inside it. That single session is why cpuCount / memoryMb / gpu are absent from the lifecycle provision contract: they configure the session rather than the container, so under one shared VM they could not mean anything per sandbox. No caller can supply them today, since the contract rejects unknown fields, and create_daemon_session set none of them either — so every lifecycle sandbox ran on the SDK defaults of 2 CPUs and 2000 MB, and a hung create had no bound at all.

The daemon now holds as many sessions as it is asked for. Option<WslcSessionGuard> became a map keyed by session id, each entry owning its VM handle, its leased store slot and its sizing. A container records the session it was placed in, and a session stays alive for exactly as long as something is using it. Sessions are sized on creation now, and a boot is bounded.

cpuCount above the host's logical processor count is refused on both surfaces, because the SDK does not oversubscribe processors. memoryMb is deliberately not checked: it is a ceiling the host backs on demand rather than a reservation, so a request past installed memory is legitimate and works.

🔗 References

Part of #1460. Second of four PRs; stacked on #1475.

PR Title
1 [WSLC] (1/4) Move the lifecycle daemon off the create-and-run image store
2 [WSLC] (2/4) Hold multiple sessions in the lifecycle daemon — this PR
3 [WSLC] (3/4) Add the session lifecycle phases and dispatch routing
4 [WSLC] (4/4) Expose provisionSession through the contract, SDKs and CLI

🔍 Validation

From src/:

Command Result
cargo fmt --all -- --check pass
cargo clippy -p mxc-sdk -p wxc --features wslc --all-targets -- -D warnings pass
cargo test -p mxc-sdk --features wslc --lib 3154 passed
cargo test -p mxc-sdk --features wslc --bins 126 passed
cargo test -p mxc-sdk --features wslc --test wslc_daemon_ipc 1 passed, 3 host-gated

On a live WSL2 host, with alpine:latest warmed into two daemon store slots:

Command Result
cargo test -p mxc-sdk --features wslc --bin wxc-wslc-daemon -- --ignored --test-threads=1 11/11 passed

The 11 include two sessions coexisting in one daemon, and a new test that provisions and runs a container in each of two sessions, releases one session entirely, and proves the other still executes. That last one fails if session routing is disabled, which the single-session tests do not catch.

Every fix in the second commit was confirmed by reverting it and watching its test fail, rather than by the test merely passing. One example: with the queued-boot drain removed, shutdown_releases_a_boot_that_landed_while_it_was_draining reports left: 0, right: 1 — the VM was never stopped.

Not run: the tests\scripts\run_wslc_*.ps1 end-to-end harnesses.

✅ Checklist

  • Signed the Contributor License Agreement
  • Linked to an issue
  • Updated documentation (if applicable)
  • Updated Copilot instructions (if build, architecture, or conventions changed)
  • If this PR changes Cargo.lock, the dependency-feed-check check passes

📋 Issue Type

  • Bug fix
  • Feature
  • Task
Microsoft Reviewers: Open in CodeFlow

@SohamDas2021
Soham Das (SohamDas2021) requested a review from a team as a code owner October 13, 2026 21:56
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@SohamDas2021
Soham Das (SohamDas2021) added this pull request to stack #1502 October 14, 2026 20:46
Copilot AI balanced review requested due to automatic review settings October 14, 2026 20:46
@SohamDas2021
Soham Das (SohamDas2021) force-pushed the sohamdas2021-pr2-multi-session-daemon branch from 02597a8 to 9398655 Compare October 14, 2026 20:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved teardown ownership and deadline defects can cause unsafe DLL access, premature store reuse, or stalled shutdown.

7 open findings
What changed in this PR

Adds multi-session infrastructure to the WSLc lifecycle daemon as part of #1460. Public lifecycle requests still use the shared implicit session.

Changes:

  • Tracks sessions, container placement, and per-session store leases.
  • Adds session sizing, CPU validation, and asynchronous boot/release handling.
  • Extends protocol messages, tests, and operational documentation.
File Description
src/​mxc-sdk/​tests/​wslc_daemon_ipc.rs Updates provision fixtures.
src/​mxc-sdk/​src/​bin/​wslc_daemon/​session_manager.rs Manages multiple sessions and their lifetimes.
src/​mxc-sdk/​src/​bin/​wslc_daemon/​control_server.rs Handles session requests and undelivered replies.
src/​mxc-sdk/​src/​backends/​wslc/​common/​wslc_bindings.rs Adds checked session termination.
src/​mxc-sdk/​src/​backends/​wslc/​common/​wsl_container_runner.rs Validates CPU sizing against host capacity.
src/​mxc-sdk/​src/​backends/​wslc/​common/​store_slots.rs Updates session-creation tests.
src/​mxc-sdk/​src/​backends/​wslc/​common/​state_aware.rs Preserves implicit-session routing.
src/​mxc-sdk/​src/​backends/​wslc/​common/​image.rs Counts outstanding pulls per session.
src/​mxc-sdk/​src/​backends/​wslc/​common/​daemon_protocol.rs Adds session messages and bumps protocol version.
src/​mxc-sdk/​src/​backends/​wslc/​common/​container_steps.rs Applies sizing, boot timeout, and checked release.
scripts/​setup-wslc.ps1 Clarifies multi-session cache warming.
docs/​schema.md Clarifies current public configuration limits.
docs/​backends/​wslc/​wslc-state-aware.md Documents session ownership, sizing, and teardown.
docs/​backends/​wslc/​wsl-container-getting-started.md Clarifies session infrastructure versus public support.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/mxc-sdk/src/backends/wslc/common/container_steps.rs Outdated
Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs Outdated
Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs Outdated
Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs
Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs
Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs Outdated
Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs Outdated
Comment thread src/mxc-sdk/src/bin/wslc_daemon/control_server.rs Fixed
Comment thread src/mxc-sdk/src/bin/wslc_daemon/control_server.rs Fixed
Comment thread src/mxc-sdk/src/bin/wslc_daemon/control_server.rs Fixed

@MGudgin Gudge (MGudgin) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Changes requested: The new multi-session reaper can fan out into unbounded release threads and, on thread-spawn failure, drop a session guard on the shared worker while forgetting its store lease. Shutdown can also discard a queued SessionBooted result and return its lease even if that guard's unchecked termination fails. The second issue is already described in the existing inline review thread; I am not duplicating its anchor. Please fix both ownership paths before merging. Additional inline comments identify the stale idle grace, nondeterministic Windows tests, abandoned named boot, cold-slot release race, quadratic poll, and undelivered-session coverage.

Verified: Base 34187f5 is the merge-base of head 9398655; the captured 14-file diff matches gh pr diff 1489. I followed SessionRelease::drop and WslcSessionGuard::drop, plus both shutdown drains. On a recently booted Windows host, cargo test -p mxc-sdk --features wslc --bin wxc-wslc-daemon -- session_manager::tests:: --test-threads=1 produced 81 passed, 7 failed, 13 ignored: seven newly added tests panic at Instant::now() - 24h. I have not run live WSL2 host tests. The owner-only daemon pipe, typed default refusals and deny-egress image path were inspected without a separate attributable security finding; existing bot threads on GPU and SDK lifetime remain independent of this review.

Other findings and prior inline threads

  • Medium — Shutdown deadline does not bound a synchronous termination. session_manager.rs:2458-2492 — introduced_by_change: the multi-session loop checks the new release deadline before each SDK terminate, not while it runs. One hung terminate can exceed the whole budget and block other VM releases. Already raised inline; no duplicate comment. Run releases on bounded workers and retain unconfirmed sessions/leases after the deadline.
  • Medium — Host-wide CPU check reads one processor group. container_steps.rs:95-117 — introduced_by_change: GetSystemInfo().dwNumberOfProcessors reports only the current group, yet both new validation surfaces call it the host total. On multi-group machines a valid host-wide CPU count can be refused. The host test copies the same oracle. Already raised inline; use a system-wide count such as GetActiveProcessorCount(ALL_PROCESSOR_GROUPS) or deliberately narrow the policy.
  • Low — Session admission intentionally has no aggregate or pending-boot cap. session_manager.rs:1254-1307 — introduced_by_change: each request can reserve a slot and spawn a VM boot; after a 600s client deadline a still-running boot retains both. The guide tells callers to enforce their own limits, so this is a documented operational risk, not an independent merge condition. Account for abandoned boots when phase 4 exposes session admission.
  • Low — VM/lease teardown rules are repeated. session_manager.rs:1024-1070,2358-2492 — introduced_by_change: normal reaping, a late boot and shutdown separately decide to return versus retain a lease after termination. Their drift already surfaces in the High shutdown finding; centralize the error-aware ownership decision while fixing it.
  • Low — Session sizing is applied in two copies. container_steps.rs:866-915 and wsl_container_runner.rs:534-576 — introduced_by_change: CPU, memory, timeout and GPU setters agree now but can drift between daemon and one-shot surfaces. Share the settings helper without dropping early host validation.
  • Low — Boot scheduling has no deterministic thread/report test seam. session_manager.rs:955-990 — introduced_by_change: hermetic tests insert PendingSession rather than checking the real ordering of queued SessionBooted versus the in-flight count; host-gated tests exist. A controlled executor would make that boundary testable without WSL2.
  • Low — Successful session RPC replies lack hermetic coverage. session_manager.rs:1394,1072 — introduced_by_change: positive ProvisionSession and DeprovisionSession replies have only host-dependent exercise, leaving a missing reply.send hard to detect without WSL2. Use the existing fake guard/channel helpers for success and failure replies.
  • Low — New memory narrowing guard has no true overflow test. container_steps.rs:881 — introduced_by_change: the purported very large 6410241024 MB host value still fits in u32, so it does not test u32::try_from failure. Test u32::MAX + 1 with a pure narrowing helper.

Claim-only and documentation notes (not merge conditions by themselves)

  • Medium — Teardown duration claim. wslc-state-aware.md:586-592 — claim_mismatch: the new guide promises a single 60s total shutdown budget, but the same guide at :367-370 and release_sessions_for_shutdown give draining and VM release separate budgets. State the two phases; do not use this claim alone to block.
  • Low — Per-caller VM isolation wording. wslc-state-aware.md:51-52 — claim_mismatch: current public lifecycle requests still use the shared implicit session (state_aware.rs:579-583); the guide later acknowledges named sessions are not yet caller-reachable. Clarify that only the daemon's internal protocol can choose another VM at this phase.
  • Low — Ignored host-test count. PR description — claim_mismatch: the unfiltered --ignored command is reported as 11/11, but this revision has 13 ignored daemon tests, including measurement-only probes. Name which selectors ran rather than suggesting every ignored test passed.

Verified pre-existing — not attributed to this PR

  • The create-and-run default store, its isolated-image refusal and the owner-only pipe existed at base. The 24-hour backdating, multi-session thread fan-out and shutdown drain command are new here, so they are not being charged to #1475. Existing Copilot review threads on COM release ordering and GPU propagation are not reproduced as our own findings.

Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs Outdated
Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs
Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs Outdated
Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs Outdated
Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs
Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs Outdated
Comment thread src/mxc-sdk/src/bin/wslc_daemon/control_server.rs Outdated
@microsoft-github-policy-service microsoft-github-policy-service Bot added the Needs-Author-Feedback Waiting for additional information or action from the issue or pull-request author. label Oct 15, 2026
Base automatically changed from sohamdas2021-wslc-store-slot-pool to main October 15, 2026 16:01
Copilot AI balanced review requested due to automatic review settings October 15, 2026 16:01
@SohamDas2021
Soham Das (SohamDas2021) force-pushed the sohamdas2021-pr2-multi-session-daemon branch from 9398655 to 2efd151 Compare October 15, 2026 16:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs Outdated
Comment thread src/mxc-sdk/src/backends/wslc/common/container_steps.rs
Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs Outdated
Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs Outdated
Copilot AI balanced review requested due to automatic review settings October 15, 2026 19:53
@SohamDas2021
Soham Das (SohamDas2021) force-pushed the sohamdas2021-pr2-multi-session-daemon branch from 2efd151 to 6dc3dde Compare October 15, 2026 19:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Comment thread src/mxc-sdk/src/backends/wslc/common/container_steps.rs Outdated
Comment on lines +1644 to +1646
if self.default_session.as_deref() == Some(session_id) {
self.default_session = None;
}
Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs Outdated
Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs Outdated
Copilot AI balanced review requested due to automatic review settings October 15, 2026 20:06
@SohamDas2021
Soham Das (SohamDas2021) force-pushed the sohamdas2021-pr2-multi-session-daemon branch from 6dc3dde to 3e303e0 Compare October 15, 2026 20:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs Outdated
Copilot AI balanced review requested due to automatic review settings October 15, 2026 21:16
@SohamDas2021
Soham Das (SohamDas2021) force-pushed the sohamdas2021-pr2-multi-session-daemon branch from 3e303e0 to 794411e Compare October 15, 2026 21:16
@SohamDas2021
Soham Das (SohamDas2021) force-pushed the sohamdas2021-pr2-multi-session-daemon branch from 794411e to 44254dd Compare October 15, 2026 21:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot AI balanced review requested due to automatic review settings October 15, 2026 21:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread docs/backends/wslc/wslc-state-aware.md
Comment thread docs/backends/wslc/wslc-state-aware.md Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs Outdated
Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs
Copilot AI balanced review requested due to automatic review settings October 16, 2026 02:34
@SohamDas2021
Soham Das (SohamDas2021) force-pushed the sohamdas2021-pr2-multi-session-daemon branch from 66e40cb to 18ad3a1 Compare October 16, 2026 02:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Comment thread src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 9709ae67-94ac-4e0a-8f90-ce6072e5354a
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 9709ae67-94ac-4e0a-8f90-ce6072e5354a
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 9709ae67-94ac-4e0a-8f90-ce6072e5354a
…ion logs

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 9709ae67-94ac-4e0a-8f90-ce6072e5354a
Copilot AI balanced review requested due to automatic review settings October 16, 2026 15:43
@SohamDas2021
Soham Das (SohamDas2021) force-pushed the sohamdas2021-pr2-multi-session-daemon branch from 18ad3a1 to dfa3d04 Compare October 16, 2026 15:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +1644 to +1646
if self.default_session.as_deref() == Some(session_ref) {
self.default_session = None;
}
… still hold

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 9709ae67-94ac-4e0a-8f90-ce6072e5354a
Copilot AI balanced review requested due to automatic review settings October 16, 2026 18:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

) -> Result<(), WorkerError> {
let (reply, rx) = oneshot::channel();
self.send(WorkerCommand::DeprovisionSession { config, reply })?;
rx.await.map_err(worker_gone)?
Comment on lines +1573 to +1583
let _ = start_session_release(
SessionRelease {
session: Some(booted),
store,
name,
},
session_ref.to_string(),
&self.releases_in_flight,
None,
Some(worker.clone()),
);

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs-Author-Feedback Waiting for additional information or action from the issue or pull-request author.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants