Create new namespaces for distro cgroups - #41512
Create new namespaces for distro cgroups#41512Feng Wang (chemwolf6922) wants to merge 10 commits into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The updated unit test logic for locating/validating the WSL init PID appears inconsistent with the actual init-distro/init-systemd thread naming, and the cgroup2 remount in MountDistroCgroupNamespace() drops nsdelegate, which can alter namespace delegation behavior.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR updates WSL’s Linux-side init/cgroup handling to create a dedicated cgroup namespace per distro (in addition to per-distro cgroup trees), aiming to preserve a “standard” systemd cgroup layout for non-critical distro processes and address regressions affecting software like rootless Docker/nerdctl.
Changes:
- Introduces a per-distro cgroup namespace FD that is created in
mini_initand passed into distro init via environment. - Updates init/session-leader/process-launch paths to move into the distro cgroup and enter the distro’s cgroup namespace where appropriate.
- Updates Windows unit tests to validate the new isolated cgroup layout expectations.
File summaries
| File | Description |
|---|---|
| test/windows/UnitTests.cpp | Updates/extends unit tests for cgroup namespace isolation and process placement. |
| src/shared/inc/lxinitshared.h | Adds a new shared env-var name for passing the cgroup namespace FD. |
| src/linux/init/WslDistributionConfig.h | Extends distro config struct to carry the cgroup namespace FD. |
| src/linux/init/util.h | Adds helpers for moving into the distro cgroup and entering a cgroup namespace; threads namespace FD through process creation APIs. |
| src/linux/init/util.cpp | Implements UtilMoveSelfToDistroCgroup() and UtilEnterCgroupNamespace(); threads namespace FD through create-process handling. |
| src/linux/init/main.cpp | Creates the per-distro cgroup namespace, passes FD to init, and mounts cgroup2 with nsdelegate. |
| src/linux/init/init.cpp | Consumes the cgroup namespace FD in init, remounts cgroup2 for the distro namespace, and applies namespace/cgroup moves for systemd and payload processes. |
| src/linux/init/config.cpp | Threads the cgroup namespace FD through child-process creation and login path setup. |
Review details
- Files reviewed: 8/8 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
🔵 Needs a closer look
Low-level cgroup namespace, mount, and process-placement changes require final human validation across supported kernel configurations.
Review details
- Files reviewed: 8/8 changed files
- Comments generated: 0 new
- Review effort level: Balanced
There was a problem hiding this comment.
🟡 Changes recommended
The updated tests remove existing verification that terminated distributions’ cgroup trees are eventually cleaned up.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 9/9 changed files
- Comments generated: 1
- Review effort level: Balanced
There was a problem hiding this comment.
🔵 Needs a closer look
The updated tests no longer verify asynchronous cleanup of terminated distro cgroups.
Review details
Suppressed comments (1)
test/windows/UnitTests.cpp:8108
- These terminations no longer verify that the per-distro cgroups are actually removed. The previous assertion covered asynchronous cleanup, and the new namespace FDs plus changed subtree layout make that cleanup more—not less—important: a leaked namespace/root would accumulate
distro-*cgroups across launches while all of the new in-namespace assertions still pass. Please retain an assertion from the utility VM's initial cgroup namespace (for example via an appropriate test helper) that waits until both terminated distro roots disappear.
// Terminate both distros.
TerminateDistribution(LXSS_DISTRO_NAME_TEST_L);
TerminateDistribution(secondDistroName);
- Files reviewed: 9/9 changed files
- Comments generated: 0 new
- Review effort level: Balanced
There was a problem hiding this comment.
🔵 Needs a closer look
The process-placement, namespace, mount, and cleanup changes require final human validation of kernel-level lifecycle behavior.
Review details
- Files reviewed: 11/11 changed files
- Comments generated: 0 new
- Review effort level: Balanced
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
🔵 Needs a closer look
The changes alter core process placement, namespace inheritance, mount behavior, and cgroup cleanup across distro startup paths.
Review details
- Files reviewed: 11/11 changed files
- Comments generated: 0 new
- Review effort level: Balanced
Summary of the Pull Request
In 2.9.8, the distro processes are separated into their own cgroups. But they remain in the same cgroup namespace. That caused compatibility issues with softwares that assume a fixed systemd cgroup layout. For example, rootless docker and nerdctl.
Fixes on Moby and nertctl are being worked on. However, to avoid issues with other software, WSL's cgroup handling should also be improved.
This PR creates new cgroup namespaces for the distros. So, to the non-critical distro processes, the systemd cgroup layout stays the same as before.
This PR also introduces a cgroup structure change to accomplish this. The systemd init is moved from
wsl-user/distro-N/systemdtowsl-user/distro-N. And the initialization of thedistro-Ncontrollers is handled by systemd instead.The processes are also moved into the non-systemd cgroup in systemdless distros. This makes sure that sub-group controllers can be enabled in the distro root.
Cgroup v2 is now enforced when distro isolation is enabled. Instead of constructing an unusable cgroup v1 layout when cgroup v1 and distro isolation are both enabled.
PR Checklist
Detailed Description of the Pull Request / Additional comments
Validation Steps Performed
Updated tests:
UnitTests::UnitTests::SystemdKillInitTerminatesDistro
UnitTests::UnitTests::IsolatedCgroupLayout
UnitTests::UnitTests::IsolatedCgroupLayoutSystemd
UnitTests::UnitTests::IsolatedCgroupLayoutDisabled
UnitTests::UnitTests::IsolatedCgroupLayoutOverridesV1
Manual tests:
rootless docker now works without the Moby fix.