wsl2: skip the SSH address lookup while no host agent runs

`limactl stop` waits until the instance reports Stopped, and each status
check of a running WSL2 instance looks up its SSH address with `wsl -d`.
WSL stops a distro 15 seconds (by default) after the last `wsl` command
in it exits, and these checks come every half second. So when another
program launches the distro right after the host agent terminates it,
the checks keep it running, and the stop times out after three minutes.

A `wsl` command without `-d` runs in the default distro, which is Lima's
when no other distro is installed. GitHub's Windows runners issue one
from time to time (`wsl -u root -e ls`, from their hosted-compute-agent).
A launch that arrives during a terminate waits, then runs right after the
distro stops. Since WSL 3.0.1 a terminate takes ten seconds instead of
under one, which widens that window; older versions hang the same way
when the launch arrives in their shorter one.

Look up the address only while a host agent runs. An instance without
one keeps the default 127.0.0.1.

CI hits this race only now and then, so the plain-host WSL2 job
forces it on every run. Its smoke test launches the default distro with
`wsl -u root -e ls` while `limactl stop` terminates the instance, only
to show that the stop completes anyway.

Signed-off-by: Jan Dubois <jan.dubois@suse.com>
This commit is contained in:
Jan Dubois committed 2026-10-06 10:50:15 -07:00
1 parent c51dd2d882
commit ea021aed31
3 files changed
+36 -1

No files matched your search

@@ -17,6 +17,17 @@ inputs:
the template or Lima's default decides.
required: false
default: ''
launch-default-distro-during-stop:
description: >
When 'true', test that `limactl stop` completes even if the instance's
distro restarts during it. GitHub's runner agent sometimes runs
`wsl -u root -e ls`, which starts the default distro, and that is the
instance's when no other is installed. The step runs the same command
while the stop terminates the instance. If the stop's status checks then
keep the restarted distro running, the stop times out. Only for the WSL2
driver.
required: false
default: 'false'
runs:
using: composite
steps:
@@ -27,6 +38,7 @@ runs:
INSTANCE: ${{ inputs.instance-name }}
TEMPLATE: ${{ inputs.template }}
VM_TYPE: ${{ inputs.vm-type }}
LAUNCH_DEFAULT_DISTRO_DURING_STOP: ${{ inputs.launch-default-distro-during-stop }}
run: |
$ErrorActionPreference = 'Stop'
# $ErrorActionPreference does not stop on a native command's exit code.
@@ -53,7 +65,25 @@ runs:
if ($back -ne 'roundtrip') {
throw "round-trip mismatch: expected 'roundtrip', got '$back'"
}
if ($env:LAUNCH_DEFAULT_DISTRO_DURING_STOP -eq 'true') {
$launcher = Start-Job -ScriptBlock {
while (-not (Get-CimInstance Win32_Process -Filter "Name='wsl.exe'" |
Where-Object { $_.CommandLine -like '*--terminate*' })) {
Start-Sleep -Milliseconds 100
}
# Give the terminate time to begin, so the launch starts the distro again.
Start-Sleep -Milliseconds 200
wsl.exe -u root -e ls *> $null
if ($LASTEXITCODE -ne 0) { throw "wsl.exe -u root -e ls exited $LASTEXITCODE" }
'launched'
}
}
Invoke-Limactl stop $env:INSTANCE
if ($launcher) {
$launched = Wait-Job $launcher -Timeout 30 | Receive-Job
Remove-Job $launcher -Force
if ($launched -ne 'launched') { throw 'default-distro launch during limactl stop did not complete' }
}
Invoke-Limactl delete --force $env:INSTANCE
- name: Dump Lima logs on failure
+1
View File
@@ -250,6 +250,7 @@ jobs:
- uses: $/.github/actions/windows_plain_smoke_test
with:
template: .\templates\experimental\wsl2.yaml
launch-default-distro-during-stop: 'true'
windows-plain-qemu:
# Like windows-plain-wsl2, for the QEMU driver. The reverse-sshfs mount
+5 -1
View File
@@ -222,7 +222,11 @@ func (l *LimaWslDriver) InspectStatus(ctx context.Context, inst *limatype.Instan
inst.SSHLocalPort = 22
if inst.Status == limatype.StatusRunning {
// Each `wsl -d` from getSSHAddress restarts WSL's idle timer for the
// distro, so skip it while no host agent runs. Otherwise, when another
// program relaunches the distro after `limactl stop` terminates it, the
// status checks keep it from going idle and the stop times out.
if inst.Status == limatype.StatusRunning && inst.HostAgentPID != 0 {
sshAddr, err := getSSHAddress(ctx, inst.Name)
if err == nil {
inst.SSHAddress = sshAddr