341 lines
21 KiB
Markdown
341 lines
21 KiB
Markdown
# WSL startup review — 2026-09-11
|
||
|
||
Owner: Codex-ytr83r `/root/wsl_startup_review`. Read-only review announced in
|
||
[issue 1 comment 317](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/1#issuecomment-317).
|
||
Root owns all live WSL, configuration, installer, packages, compiler and GUI work.
|
||
No WSL command, process stop, account/configuration change, installation or Git
|
||
mutation was performed by this reviewer. Only this report and ignored
|
||
`.local/wsl-startup-review/` evidence were written.
|
||
|
||
## Finding and current intervention
|
||
|
||
The evidence supports **successful initial WSL2 execution followed by failures
|
||
within the utility-VM creation path, before either requested script started**.
|
||
It does not locate the later failure within VM creation or establish a cause.
|
||
In particular, a live vmmemWSL process does not prove that the guest kernel or
|
||
its control channel became ready on that attempt.
|
||
|
||
This review's original baseline is the same host boot at
|
||
`2026-09-11T13:57:30.5868600Z`. Peer 956atf and 9e8r6t guest/network outcomes
|
||
are different-host evidence and are not used to diagnose this host.
|
||
|
||
During review the user directed root to the proposed networking solution in
|
||
[comment 316](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/1#issuecomment-316).
|
||
Root reported that it would preserve the baseline, apply `networkingMode=mirrored`
|
||
and `dnsTunneling=true`, and execute the requested WSL shutdown/restart. The host
|
||
VPN must remain untouched. This is a new root-owned intervention, superseding
|
||
the earlier no-configuration plan. Its execution/result is not independently
|
||
verified by this reviewer. Timestamp the change and restart separately: a later
|
||
success cannot, by itself, distinguish the mode change from restarting, elapsed
|
||
time, or compiler-load differences.
|
||
|
||
## Local evidence and limits
|
||
|
||
- Re-read the raw installer stdout as UTF-16: download, installation and successful
|
||
registration are explicit. Result JSON records exit 0 at
|
||
`14:19:47.9073217Z`, from start `14:03:45.5401681Z`, PID 7824. This does not
|
||
measure guest boot duration separately from the download/install.
|
||
- Root's normalized observation record reports shell 20913 exit 0, Ubuntu 26.04
|
||
LTS, kernel `6.18.33.2-microsoft-standard-WSL2`, x86_64, uid 0, readable repo mount,
|
||
Git/Python and WSLg environment/endpoints. Follow-ups 1905 and 97517 exited 0.
|
||
These are explicitly normalized root observations, not saved raw guest stdout
|
||
independently replayed by this reviewer.
|
||
- The same record reports 99983 exit -1 and 92958 exit 1 with
|
||
`Wsl/Service/CreateInstance/CreateVm/0x800705b4`, before initial `bash -n` and
|
||
file-backed inventory execution respectively. No apt or Linux Cargo began.
|
||
Exact start/end timestamps and raw stderr for these two attempts are absent
|
||
from this saved record; do not map individual Windows events to either handle
|
||
more precisely than the evidence permits.
|
||
- Accessible VmSwitch events show the original guest NIC connected successfully
|
||
at `14:15:15.4708445Z`, disconnected with `STATUS_SUCCESS` at
|
||
`14:27:50.3605955Z`, and Vmbus pause completed at `14:28:21.6389620Z`.
|
||
These establish NIC lifecycle activity, not the reason for VM closure or a
|
||
subsequent startup timeout. Earlier transient `Drive Not Ready` NIC status
|
||
messages precede successful connection and the successful Linux shell; they
|
||
are not proof of a physical disk failure.
|
||
- Event 285 warnings occur both before and after the successful first shell.
|
||
The rendered warning gives execution, queued and expected durations as 0 ms.
|
||
That message is not a measured delay explaining either timeout. The friendly
|
||
name `WSL (Hyper-V firewall)` is not evidence that a firewall blocked a packet.
|
||
- Host metadata captured `14:40:47.2735325Z`: VMware20,1, 2 logical CPUs,
|
||
8,588,644,352 bytes physical RAM; 3,766,584 KiB available memory and
|
||
29,250,076,672 bytes C: free. WslService, vmcompute and hns were running.
|
||
Cargo and rustc were present; no wsl.exe or vmmemWSL matched the bounded process
|
||
query. This is a point-in-time observation, not utilization/pressure telemetry
|
||
from the failing intervals and not proof of global host health.
|
||
- Event query was bounded to `13:57:00Z`–`14:35:00Z`, enabled nonempty channels,
|
||
at most 80 newest events per accessible channel. It yielded exactly 80
|
||
VmSwitch records spanning `14:15:04.2170052Z`–`14:34:51.0512848Z`, including
|
||
18 warnings; older matching records may be omitted. Compute, Worker, VID,
|
||
StorageVSP, Hypervisor and HNS channels denied access to this token. No matching
|
||
Lxss or Subsystem-Linux log was exposed. The HNS wildcard also reported no
|
||
matching accessible log after access errors; that is not proof HNS is absent.
|
||
No channel was enabled and no elevation attempted. No WSL ETL trace exists in
|
||
this review.
|
||
|
||
The prior `HCS_E_HYPERV_NOT_INSTALLED` belongs to the earlier boot/installation
|
||
attempt and is superseded for basic virtualization availability by the actual
|
||
executed WSL2 kernel. It remains preserved as history.
|
||
|
||
## Ranked diagnostic hypotheses
|
||
|
||
These are priorities for discrimination, not probability estimates or diagnoses.
|
||
|
||
| Rank | Hypothesis | Supporting/limiting facts | Discriminating observation |
|
||
| --- | --- | --- | --- |
|
||
| 1 | Utility-VM boot/control-channel readiness did not finish in time after lifecycle transition | `CreateVm` context and later failure before scripts; NIC disconnect/pause exists. Current WSL source includes HCS startup and timed mini_init/control connections inside this path. No trace identifies the failing call. | Trace error location and guest/control events; first guest-ready marker in the one trial. |
|
||
| 2 | Resource or scheduling latency contributed on this nested VM | Two CPUs, 8 GB host and active compiler; initial startup appeared slow. Available RAM/disk snapshots are nonzero and cannot establish pressure or causation. | Record compiler state, elapsed startup, CPU/memory/disk observations at the trial; success after less load is correlation, not proof. |
|
||
| 3 | WSL network initialization contributed to the creation failure | Network setup is part of utility-VM initialization and is the user's current intervention. Accessible NIC activity is real, but warnings also occur during success; this host has no saved failing guest IP/DNS/HTTPS probe. | Separate `CreateNetwork`/error trace from shell-ready and independent bounded IP, DNS, HTTPS results after the authorized mode change. |
|
||
| 4 | Distro first-run/systemd/cloud-init state contributes to later distro usability | Root user-session warning, unfinished cloud-init and no uid 1000 are recorded. Shells nevertheless executed; these do not explain a `CreateVm` error without further evidence. | Once shell-ready, capture PID 1, cloud-init status, failed units and root user journal in that same live shell. |
|
||
|
||
The version-matched [WSL 2.7.13 utility-VM source](https://github.com/microsoft/WSL/blob/2.7.13/src/windows/service/exe/WslCoreVm.cpp)
|
||
creates and starts the HCS compute system, then accepts mini_init and notification
|
||
connections, reads guest capabilities, and initializes networking under a nested
|
||
context. In the saved file these are lines 326, 350, 441–447 and 536 onward;
|
||
`AcceptConnection` at 829–840 uses the kernel boot timeout. The
|
||
[session source](https://github.com/microsoft/WSL/blob/2.7.13/src/windows/service/exe/LxssUserSession.cpp)
|
||
places `_CreateVm` under `Context::CreateVm` at 2840. This explains why the visible
|
||
context does not mean Linux definitely never booted. It does not identify the
|
||
line that failed on this machine. Sources fetched by tag are preserved and hashed
|
||
below; no claim of binary/source attestation is made.
|
||
|
||
## One root-owned controlled trial
|
||
|
||
Use the already authorized post-change restart as the **one trial**, not an
|
||
additional duplicate launch. If root has already launched it, apply the following
|
||
observability to that handle. Record baseline/configuration hashes, shutdown
|
||
terminal result, UTC/monotonic start, command, compiler state and process handle.
|
||
Avoid a second simultaneous WSL client. Resource serialization is preferable;
|
||
if the current Windows compile remains active, explicitly record that limitation.
|
||
|
||
Start one interactive process with an owned PTY, preserving stdout/stderr:
|
||
|
||
```powershell
|
||
wsl.exe --distribution Ubuntu-26.04 --user root --cd / --exec /bin/bash --noprofile --norc -i
|
||
```
|
||
|
||
This reuses the already observed root account and starts from guest `/`, reducing
|
||
dependence on the current Windows directory and shell profiles. It creates no
|
||
account and does not complete OOBE. Observe in intervals at most 60 seconds, with
|
||
a five-minute startup observation cap. If a terminal WSL error occurs, record
|
||
exact stderr/exit/time and do not repeat. If still active at the cap, record
|
||
`startup observation timed out; client still active`, preserve its identity for
|
||
root, and do not start a competing command or infer a terminal exit. Only root
|
||
controls disposal of its process.
|
||
|
||
Once a prompt exists, issue these inside the **same** shell, preserving each
|
||
result independently. A readiness marker before all diagnostics separates
|
||
startup failure from guest-tool failures:
|
||
|
||
```bash
|
||
printf 'ARCADIA_GUEST_READY\n'
|
||
date -u -Iseconds
|
||
uname -a
|
||
id
|
||
cat /proc/sys/kernel/random/boot_id
|
||
cat /proc/uptime
|
||
ps -p 1 -o pid,comm,args
|
||
timeout 10s systemctl is-system-running
|
||
timeout 10s systemctl --failed --no-pager
|
||
timeout 10s cloud-init status --long
|
||
timeout 10s journalctl -b -u user@0.service --no-pager -n 80
|
||
ip -brief address
|
||
ip route
|
||
timeout 15s ping -c 3 -W 3 1.1.1.1; printf 'PING_EXIT=%s\n' "$?"
|
||
timeout 15s getent hosts google.com; printf 'DNS_EXIT=%s\n' "$?"
|
||
command -v curl
|
||
curl -4 --connect-timeout 10 --max-time 20 https://api.ipify.org; printf '\nHTTPS_EXIT=%s\n' "$?"
|
||
printf 'ARCADIA_DIAGNOSTICS_DONE\n'
|
||
```
|
||
|
||
Missing commands are prerequisite findings, not network failures; do not install
|
||
tools merely to satisfy this diagnostic. Do not use `set -e`: failed systemd,
|
||
ICMP or DNS results must not suppress later independent probes. Failed ping
|
||
alone can reflect ICMP filtering; successful DNS and HTTPS are separate results.
|
||
These are the owner's comment 316 checks with time bounds. No routes, NAT,
|
||
resolv.conf, VPN, firewall or service configuration changes are part of the trial.
|
||
|
||
Retain this shell while root reviews output and any subsequently authorized work.
|
||
Two guest markers and responsive commands prove that this startup became usable;
|
||
they do not prove reliable future cold starts, package installation, Linux builds
|
||
or GUI rendering. If it fails again before the first marker, the next useful
|
||
diagnostic is a root-reviewed WSL ETL capture of a separately justified future
|
||
reproduction, rather than repeated blind launches or a reboot.
|
||
|
||
[Microsoft's tracing documentation](https://github.com/microsoft/WSL/blob/master/doc/docs/debugging.md)
|
||
identifies `Microsoft.Windows.Lxss.Manager` guest, error, VM lifecycle, network
|
||
lifecycle and hvsocket events. These can distinguish HCS start, guest connection
|
||
and networking stages. The general collection script was inspected only: it
|
||
starts recording and can invoke WSL during collection, so it was not executed
|
||
under this worker's no-WSL lease. No dump, trace, upload or issue submission to
|
||
Microsoft occurred. Root should review its exact capture scope before running it.
|
||
|
||
## SHA256 evidence identities
|
||
|
||
Original experiment prefix:
|
||
`harness/experiments/wsl-postboot-ytr83r-20260911/postvirtualization/`.
|
||
|
||
| File | Bytes | SHA256 |
|
||
| --- | ---: | --- |
|
||
| `stdout.log` | 296 | `83B346901876FAB366E976BB770CA1B7D935EBAB4A50E843FDC630536A800BE2` |
|
||
| `result.json` | 137 | `34EC331D05FAD9CCA23A1683DA5B6F96C7FF24B8BCD6439A0ECBA04F5ECF6078` |
|
||
| `normalized-observations.json` | 1574 | `0CC3DC881F43DD396B0C4C8FEA0BAF806FBE0067F212AED05FE6CB79312A05AD` |
|
||
|
||
Reviewer evidence prefix: `.local/wsl-startup-review/`; manifest `sha256.json`.
|
||
|
||
| File | Bytes | SHA256 |
|
||
| --- | ---: | --- |
|
||
| `event-channels.json` | 700 | `716238637B05BD9562F143FD7EEF53914FCAF44D7D7E861571A74C35D11FD294` |
|
||
| `event-query-errors.txt` | 1894 | `828BEA2793062C832D45404360138D4CA182FC2D69817B364A594A2989713865` |
|
||
| `events.json` | 50370 | `89DF6BEB814CCFC878860EEE5BDF11536DE716C7FA689DB1DF60594749165FE3` |
|
||
| `host-metadata.json` | 1866 | `74E868A1A7D5915DAE7EF830ED06328F56F05D068E89FA1B5BCAB0A75FB552B9` |
|
||
| `LxssUserSession-2.7.13.cpp` | 163888 | `3564DC74C776BF151C661D2FE35D4AF2FEB655EE360F7886B2CD636E95160CFF` |
|
||
| `WslCoreVm-2.7.13.cpp` | 117607 | `429F6095EC4FD2433A372E3FE80E659AFA8CBC679AEA18EC2C15A3651B9F8778` |
|
||
|
||
Scope limitation: the review contains no application change or executable test.
|
||
The proposed command sequence is not a claimed execution result. Root retains
|
||
the release ledger/Wiki update and all remaining Linux acceptance gates.
|
||
|
||
## Follow-up: post-316 failure and held trace preparation
|
||
|
||
This section is distinct from the original report, whose SHA256 was
|
||
`CDFC0F04051451C2A7BEB0427EDDCC1D73ABC84FBC65E9947DB2DEFCEA91B465`.
|
||
|
||
Root supplied the following terminal observations after the original review:
|
||
authorized WSL shutdown exited 0 at `14:42:18.920Z`; Windows Cargo 55371 exited
|
||
101 at `14:43:51.917Z`; no cargo/rustc was observed when launching the subsequent
|
||
WSL trial. Trial 52988 then exited 1 with the same
|
||
`CreateVm/0x800705b4` before a prompt. No guest commands or network probes ran.
|
||
The mirrored+dnsTunneling configuration hash was
|
||
`4A4D2D7C9684AFDF5A106DEA4B3AB195E706F8859182E09F4AA05FFF6C5D1C63`.
|
||
These are root's direct-tool observations, not raw logs independently obtained
|
||
by the reviewer. Failure after compiler exit weakens an explanation requiring
|
||
concurrent Cargo; it does not exclude residual scheduling or other host latency.
|
||
This trial did not establish that mirrored networking fixed startup.
|
||
|
||
The user subsequently directed root to
|
||
[comment 328](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/1#issuecomment-328):
|
||
`networkingMode=virtioproxy`, WSL shutdown/start and guest IP/route, ping,
|
||
github.com DNS and HTTPS checks. Root owns that new trial. The host VPN is
|
||
immutable and AmneziaWG must not be modified or inspected. **The following
|
||
capture is preparation held behind that path, not a request to execute it. If
|
||
the new networking works, stop troubleshooting and leave this capture unused.**
|
||
|
||
### Actual capture prerequisite
|
||
|
||
Read-only token metadata at `14:48:20.6566593Z` reports both elevated Administrator
|
||
and Performance Log Users membership false. WPR and tracerpt executables exist.
|
||
The exact official
|
||
[2.7.13 collector](https://github.com/microsoft/WSL/blob/2.7.13/diagnostics/collect-wsl-logs.ps1)
|
||
requires Administrator. Its networking mode performs extra guest probes and
|
||
packet captures; its optional restart mode removes the WSL HNS network and
|
||
stops the WSL service. A failed WPR start triggers a global cancel/retry. The
|
||
wrapper also gathers broad configuration logs, archives them locally and removes
|
||
its unarchived folder. It does not itself upload the archive. This wrapper is
|
||
therefore not selected for the bounded startup capture.
|
||
|
||
[Microsoft documents ETW controller privileges](https://learn.microsoft.com/en-us/windows/win32/etw/controlling-event-tracing-sessions)
|
||
as elevated administrative access, Performance Log Users membership or listed
|
||
service accounts. This token lacks those supported controller rights. No
|
||
same-token capture is claimed available, no privilege/group change is proposed,
|
||
and no self-elevation or collection attempt occurred.
|
||
|
||
### Concrete held artifact
|
||
|
||
Root requested a reviewable script before any possible user action request.
|
||
Prepared `.local/wsl-startup-review/capture-startup.ps1` and adjacent
|
||
`providers-startup.txt`. The script requires PowerShell 7 and Administrator at
|
||
the top and requires the same Windows User profile that owns Ubuntu-26.04.
|
||
It has no self-elevation. If root later approves a traced reproduction, its
|
||
exact command in that account's Administrator PowerShell is:
|
||
|
||
```powershell
|
||
pwsh.exe -NoProfile -File "C:\Users\User\Documents\Git\ARCADIA-Studio\.local\wsl-startup-review\capture-startup.ps1"
|
||
```
|
||
|
||
The script generates a fresh GUID-named directory and trace session. Its exact
|
||
controller command shape is:
|
||
|
||
```powershell
|
||
logman.exe create trace ARCADIA-WSL-<fresh-guid> -o <fresh-directory>\startup.etl -f bincirc -max 64 -bs 64 -nb 16 64 -ct perf -pf <fresh-directory>\providers-startup.txt -ets
|
||
logman.exe stop ARCADIA-WSL-<same-guid> -ets
|
||
```
|
||
|
||
These are descriptive command shapes; the complete script supplies and records
|
||
the actual arguments. Local `logman create trace/start/stop /?` was read without
|
||
starting tracing. The
|
||
[official command reference](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/logman-create-trace)
|
||
documents direct `-ets` operation without saved/scheduled collector sets, provider
|
||
files, circular output, maximum file size and buffer controls. No WPR global
|
||
session is canceled. Each controller process has a 30-second wait and can stop
|
||
only its own client process; an uncertain start never launches the WSL probe.
|
||
Cleanup attempts to stop only the newly GUID-named session, including after an
|
||
uncertain start. An unconfirmed stop is explicitly reported for root to inspect;
|
||
there is no broad stop, deletion or reset fallback.
|
||
|
||
The minimal profile contains only these two official provider identities, copied
|
||
from the version-matched
|
||
[WSL profile](https://github.com/microsoft/WSL/blob/2.7.13/diagnostics/wsl.wprp):
|
||
|
||
```text
|
||
{B99CDB5A-039C-5046-E672-1A0DE0A40211} 0xffffffffffffffff 0xff
|
||
{D90B9468-67F0-5B3B-42CC-82AC81FFD960} 0xffffffffffffffff 0xff
|
||
```
|
||
|
||
These are WSL manager and WSL user executable providers, exposing WSL lifecycle,
|
||
guest/control and visible/error events. The script verifies the exact two-line
|
||
scope before running. There are no HNS, packet, VPN, general CPU/kernel stack or
|
||
system-wide network-inventory collectors. WSL-emitted event payloads can still
|
||
contain paths, distro/configuration identifiers, IP information, kernel messages
|
||
and command/error details; local analysis should stay on WSL startup events.
|
||
The trace is evidence to locate an error, not a guaranteed full HCS/network
|
||
diagnosis. Missing provider events, circular overwrite or undecodable records
|
||
remain explicit limits.
|
||
|
||
After trace-start exit 0, exactly one hidden, directly owned WSL process runs
|
||
Ubuntu-26.04 as root, `--cd /`, `/bin/bash --noprofile --norc -c` with a literal
|
||
multi-line probe passed through .NET ArgumentList. It first emits
|
||
`ARCADIA_GUEST_READY`, records uname/id/boot ID, then performs the comment 328
|
||
guest IP/route, two-packet ping, github.com DNS and HTTPS-header checks, each with
|
||
bounded waits, before `ARCADIA_DIAGNOSTICS_DONE`. No probe failure suppresses a
|
||
later independent check. The probe performs no installation or configuration.
|
||
The script reads only a SHA256 of `.wslconfig`, not host network/VPN state.
|
||
|
||
The observation cap is five minutes from process launch. If the owned Windows
|
||
WSL client is still running, it is stopped by its retained Process object only;
|
||
no process-tree kill, guest kill, distro terminate or WSL shutdown occurs. The
|
||
guest/VM may consequently remain alive. No retry follows. Raw stdout/stderr byte
|
||
streams, UTC and elapsed time, exact arguments, PID, exit/timeout/stop status,
|
||
trace start/stop output and SHA256 manifest are saved under the fresh directory.
|
||
Stream-drain completion is recorded; an incomplete stream must not be treated
|
||
as complete stderr. Cleanup runs in `finally`; interrupted hosts/power loss can
|
||
still leave the named trace active, so retain the session identity from result
|
||
or progress output.
|
||
|
||
Storage is a 64 MB circular ETL plus small probe/controller/metadata files; ETW
|
||
buffers are configured to 16–64 of 64 KB (approximately 1–4 MiB plus overhead).
|
||
Circular recording bounds growth but can overwrite the beginning; verify trace
|
||
coverage starts before the reproduction and check lost-event information.
|
||
Preserve the complete fresh directory for review. No automatic deletion,
|
||
compression, registry export, upload or remote submission is included. Stopping
|
||
the owned direct ETW session is normal runtime cleanup; there is no saved data
|
||
collector set to delete. The result can later be opened locally in WPA or
|
||
converted with tracerpt, preserving the original ETL and recording decoding
|
||
limits. Neither analyzer/decoder was run here.
|
||
|
||
Validation: PowerShell parser reports zero errors and confirms version 7.0 plus
|
||
Administrator requirements. Both provider GUIDs match the official 2.7.13 XML.
|
||
Static review checked the single WSL launch, literal argument handling, owned
|
||
process/session cleanup, fail-before-probe branch and absence of configuration,
|
||
VPN inspection and upload commands. No elevated process, trace, WSL or probe
|
||
execution was performed. This is a prepared artifact, not a tested controller
|
||
or a Linux acceptance result.
|
||
|
||
| Follow-up file in `.local/wsl-startup-review/` | SHA256 |
|
||
| --- | --- |
|
||
| `collect-wsl-logs-2.7.13.ps1` | `8CD3E69F978B2FEA2651597E147D88BFC7CBB5E6607F076152DEC8C2862DF3A4` |
|
||
| `wsl-2.7.13.wprp` | `3F829A9AF733D6DCE9454A1DF2E2AA07096ACAAED5B6865FFB5C202D089479F2` |
|
||
| `trace-prerequisites.json` | `1C94870BFB9D64FB672CA7CB8F7703CC09C0FA4097337F4AFA69AE4BD422A199` |
|
||
| `capture-startup.ps1` | `BD878A6E92F2D57EB291B277104AB9FCC42273D53F7285121C85685223EF5D1E` |
|
||
| `providers-startup.txt` | `257FC8874B3C42D6AC27CCCE2031111C937CDB0A500039057DA37C202E17261C` |
|