Skip to content

[WSLC] (1/2) Set operation and nativeCode on container lifecycle errors - #1671

Open
Soham Das (SohamDas2021) wants to merge 2 commits into
mainfrom
sohamdas2021-wslc-lifecycle-metadata-pr1
Open

Soham Das (SohamDas2021) wants to merge 2 commits into
mainfrom
sohamdas2021-wslc-lifecycle-metadata-pr1

Conversation

@SohamDas2021

@SohamDas2021 Soham Das (SohamDas2021) commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

📖 Description

When a WSLc container lifecycle operation failed in a WSLc SDK call, the error named the call and its HRESULT only inside message. Its operation and nativeCode fields stayed empty, so a caller had to parse the message to tell, for example, a host port already in use from any other start failure.

WSLc container lifecycle errors now fill both fields when a WSLc SDK call fails:

  • operation is the SDK function and nativeCode is its HRESULT. Starting a container whose host port is already in use returns backend_error with operation WslcStartContainer and nativeCode 0x80072740.
  • This covers creating sessions, provisioning (including image pulls), starting, stopping, deprovisioning, and exec. A provision that was waiting for a session whose boot failed gets the boot failure's details.
  • An image pull that runs out of time reports operation WslcPullSessionImage without nativeCode, because no HRESULT exists.
  • When an exec's end cannot be confirmed, the error names the first failed call to kill the process (WslcSignalProcess) or read its exit code (WslcGetProcessExitCode), unless an earlier SDK call in that exec already failed.
  • If an exec's end cannot be confirmed and deleting its container also fails, the error keeps the original failure's details. The delete failure's details are used only when the original failure had none.

Error codes, messages, exit codes, and create-and-run results are unchanged.

The WSLc daemon protocol version changes from 9 to 10. A client refuses a running daemon from an older version, so upgrading means letting that daemon idle out or stopping it, which ends the containers it holds.

The lifecycle error contract now lists WSLc as filling operation and nativeCode, and the WSLc lifecycle guide describes the fields and the new protocol version.

No spec is required: the fields already exist in the error contract, and the daemon protocol is internal to the WSLc backend.

Limitation: errors from waiting on a process started in a container through the Rust, .NET, and Node SDK process APIs still lack these fields. That is planned as a follow-up PR for #1644.

🔗 References

Refs #1644

Follows #1240, which carried the failure's classification across the WSLc daemon protocol but not the failing call or its status.

🔍 Validation

Run on Windows 11 (build 26300, x64) with WSL 3.0.5. Cargo commands run from src.

  • cargo fmt --all -- --check: passed.
  • cargo clippy -p mxc-sdk --all-targets --features wslc -- -D warnings: passed.
  • cargo test -p mxc-sdk --lib --features wslc: 2,944 passed, 8 ignored.
  • cargo test -p mxc-sdk --bin wxc-wslc-daemon --features wslc: 178 passed, 13 ignored.
  • cargo test -p mxc-sdk --test wslc_daemon_ipc --features wslc: 1 passed, 3 ignored.
  • The new and extended unit tests cover each failure path above. The test for provisions waiting on a failed session boot fails if those provisions lose the boot failure's details.

Live WSL2 host, with a release build from cargo build --features wslc --release --target x86_64-pc-windows-msvc:

  • From the repository root, pwsh -File tests\scripts\run_wslc_all_tests.ps1 -WxcExecPath src\target\x86_64-pc-windows-msvc\release\wxc-exec.exe: all 50 results passed. That is 49 create-and-run results and the lifecycle suite, which passed 140 of 140 checks, including the port-collision checks for backend_error, operation WslcStartContainer, and nativeCode 0x80072740.
  • cargo test -p mxc-sdk --bin wxc-wslc-daemon --features wslc -- --ignored --test-threads=1 --skip measure_whether_session_sizing_reserves_or_caps --skip a_session_larger_than_the_host_is_refused: 11 passed. The oversize-session test passed on its own with --ignored --exact session_manager::tests::a_session_larger_than_the_host_is_refused. The sizing measurement was not run, since it reports figures rather than checking behavior.
  • cargo test -p mxc-sdk --test wslc_daemon_ipc --features wslc -- --ignored --test-threads=1: 3 passed.
  • cargo test -p mxc-sdk --lib --features wslc -- --ignored --test-threads=1 store_slots::host_tests filesystem_probe::launch_tests::: 7 passed.
  • cargo test -p mxc-sdk --features wslc --test wslc_stdin_handle_probe -- --ignored --nocapture --test-threads=1: 1 passed.
  • The ignored library and daemon tests load wslcsdk.dll from beside the test binary, so it was copied from target\debug into target\debug\deps first.
  • Node, from sdk\node\tests\integration with MXC_ENABLE_WSLC_TESTS=1: node --test --test-force-exit --test-reporter=spec --test-reporter-destination=stdout dist/wslc-state-aware.test.js passed 2 of 2, and the same command with dist/wslc-e2e.test.js passed 8 of 8. None were skipped.
  • .NET, with SDK 10.0.403: dotnet publish sdk\dotnet\Microsoft.Mxc.Sdk.Tests\Microsoft.Mxc.Sdk.Tests.csproj -c Release -f net10.0 -r win-x64 -p:MxcWithIsolationSession=true -p:MxcWithWslc=true -p:MxcTestPrebuiltNativeLibrary=<mxc_ffi.dll> --self-contained true -o <out>, then Microsoft.Mxc.Sdk.Tests.exe -class *.MxcLifecycleWslcE2ETests -class *.MxcContainerWslcE2ETests -result-xml <file> with MXC_ENABLE_WSLC_TESTS=1: 20 passed, none skipped. The test project's own native build failed in rc.exe under MSBuild on this machine, so its command, cargo build -p mxc_ffi --features "dotnetsdk test-support isolation_session wslc" --target x86_64-pc-windows-msvc --target-dir target\dotnet-test-support, was run directly and its mxc_ffi.dll passed in.
  • The Node and .NET runs were on the first revision of this PR. The review fixes don't change the SDK bindings, so they weren't rerun.

Windows CI commands, with CARGO_TARGET_DIR set to a short path because this worktree's path pushes the hyperlight helper build past the Windows path length limit:

  • cargo test --locked --release --target x86_64-pc-windows-msvc --no-default-features --features "hyperlight isolation_session microvm wslc": passed. 4,935 passed and 64 ignored across 54 test binaries, including doc tests.
  • cargo clippy --target x86_64-pc-windows-msvc --locked --all-targets --all-features --release -- -D warnings: passed.

✅ Checklist

  • Signed the Contributor License Agreement
  • Linked to an issue
  • For features or changes requiring a spec: linked the issue with maintainer-applied feature-accepted
  • For implementation: linked the required approved and merged design/API spec, or explained why no spec is required
  • Feature issue remains open unless this PR completes all agreed implementation, validation, and documentation
  • 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 (see pull request builds)

📋 Issue Type

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

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@SohamDas2021
Soham Das (SohamDas2021) requested a review from a team as a code owner November 4, 2026 20:13
Copilot AI balanced review requested due to automatic review settings November 4, 2026 20:13
@azure-pipelines

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

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

When timeout or cancellation leaves termination unconfirmed, a WslcGetProcessExitCode failure is only logged, causing quarantine to lose or misattribute the original SDK error details.

1 open issue
What changed in this PR

This PR extends WSLc’s existing lifecycle error classification to carry the failing SDK function and HRESULT through the daemon to callers, addressing part of #1644.

Changes:

  • Propagates structured failure details through session, container, image-pull, and exec operations.
  • Bumps the internal daemon protocol from 9 to 10 and documents upgrade implications.
  • Adds propagation tests and extends the live port-collision regression checks.
File Description
tests/​scripts/​run_wslc_state_aware_tests.ps1 Checks operation and HRESULT for port collisions.
src/​mxc-sdk/​src/​bin/​wslc_daemon/​session_manager.rs Carries failure details through workers and quarantine handling.
src/​mxc-sdk/​src/​bin/​wslc_daemon/​control_server.rs Includes failure details in daemon replies and exec frames.
src/​mxc-sdk/​src/​backends/​wslc/​common/​wsl_container_runner.rs Converts step errors to existing create-and-run responses.
src/​mxc-sdk/​src/​backends/​wslc/​common/​state_aware.rs Maps daemon failure details into lifecycle errors.
src/​mxc-sdk/​src/​backends/​wslc/​common/​image.rs Attaches operation and status details to image failures.
src/​mxc-sdk/​src/​backends/​wslc/​common/​error.rs Introduces a step error carrying structured diagnostics.
src/​mxc-sdk/​src/​backends/​wslc/​common/​daemon_protocol.rs Adds failure payloads and advances the protocol version.
src/​mxc-sdk/​src/​backends/​wslc/​common/​daemon_client.rs Preserves diagnostics when receiving daemon errors.
src/​mxc-sdk/​src/​backends/​wslc/​common/​container_steps.rs Records SDK call names and HRESULTs in step failures.
docs/​development/​architecture/​container-lifecycle.md Documents WSLc diagnostic-field availability.
docs/​backends/​wslc/​wslc-state-aware.md Describes structured errors and protocol version 10.

Review effort: Balanced

@SohamDas2021 Soham Das (SohamDas2021) changed the title [WSLC] Set operation and nativeCode on container lifecycle errors [WSLC] (1/2) Set operation and nativeCode on container lifecycle errors Nov 5, 2026

@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

Filing findings 1 and 2 only, both Medium and nonblocking. Rechecked against head 08eb260cc959afe5766789a414fc37073e417c6f and merge-base 92e767a8278c785892c07d8bada456174f199405; both inline anchors are added lines. This is a static review, not an approval or a claim that local tests were run.

Verified behavior

  • WorkerError::kind() and Display currently handle both the dedicated variants and Step (src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs:212-251). Finding 1 concerns overlapping representations, not an observed misclassification.
  • Quarantine already preserves original API detail when present and falls back to deletion detail only when absent (src/mxc-sdk/src/bin/wslc_daemon/session_manager.rs:2618-2663, specifically api_failure.or(delete_error.api_failure)). Finding 2 concerns detail lost before reaching that code, not incorrect quarantine precedence or cleanup.

Findings outside the diff

None filed separately; finding 2 is anchored on the added metadata consumer and explains its dependency on unchanged helper branches.

Verified pre-existing behavior - not charged as new behavior

  • The log-only WslcSignalProcess / unconfirmed WslcGetProcessExitCode branches and the final post_launch_error: None already exist at the merge-base. They are not alleged to be newly broken kill or cleanup behavior. Finding 2 is newly_exposed_by_change: this PR adds structured SDK-failure propagation, but these existing producers leave a gap in that new behavior. No standalone pre_existing finding or merge condition is being posted.

Attribution ledger: finding 1 kept as introduced_by_change; finding 2 kept as newly_exposed_by_change.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings November 11, 2026 02:55

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.

🟢 Approval recommended

No active review issues remain for the WSLc error-propagation changes.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants