Skip to content

windows: lease not freed when the berth run process dies after attach (no reaper for a dead attached pid) #104

Closed

Description

@azrael-229

v0.3.1 (no changes to this in v.0.3.2) windows-amd64, daemon --gpu 0 --poll 2s, one RTX 5070 Ti.

Steps to reproduce (what happened on this box):

  1. berth run --as hog -- powershell -NoProfile -ExecutionPolicy Bypass -File <app>.ps1
  2. Daemon log: granted lease=hog-1 ... waited=1ms then attached lease=hog-1 pid=27508 (16 ms later).
  3. The run process tree was force-killed (taskkill /F /T) while the app was inside the lease. (Any death of the run process works: crash, power, /F kill.)
  4. The lease stayed HOT (later contested) with PIDS [] and HOLDS 0 MiB for as long as it was observed (26+ minutes; still alive at check time). No lease.released/lease.freed event, no timeout, no reaper — the daemon never re-checked whether the attached pid was still alive.
  5. Recovery: berth stop hog → draining → released on the next tick → freed. berth reclaim is of no help for this case: it reports "0 processes recorded under stuck leases" because the board's PIDS is empty, so it names nothing to stop.

Expected: the daemon to notice the attached pid is dead and free (or at least mark stuck) the lease, the same way a released-but-not-freed lease is handled.

Events (abridged): requested → granted (waited 1 ms) → [26 m 54 s silence] → draining (stopped by berth stop) → released (held=26m54s) → freed.

Activity

  1. azrael-229 commented on Oct 21, 2026

    @azrael-229
    Author

    Full checklist report from the run, attached. generated with the locally patched check.ps1 — see #105

    final-report.txt

  2. T-Crypt commented on Oct 21, 2026

    @T-Crypt
    Owner

    PR #108 fixes it. The broker now checks the attached process itself on every tick. When it finds the process gone on two ticks in a row, it releases the lease the same way a disconnect would, then frees it once the card shows nothing of the run left. A PID the kernel reused counts as gone. The broker leaves a lease alone if it names a container or still has a process on the card, and it signals nothing. The event log shows lease.orphaned, then lease.released and lease.freed.

    Your taskkill /F /T case now frees the lease within a few seconds at --poll 2s, and you don't need berth stop hog to recover. It ships in v0.3.3.

    Thanks for attaching the full report. It turned up two more Windows problems: a nameless 10.7 GB holder and a stowaway list full of desktop apps. I wrote both up on #103.

  3. azrael-229 commented on Oct 21, 2026

    @azrael-229
    Author

    Confirmed on the same build. Exact issue repro: dummy engine under lease, whole run tree force-killed (taskkill /F /T) 75 s after attach. v0.3.1: HOT for 26+ minutes. This build: lease.released 0.7 s after the kill, lease.freed 1.1 s after. Engine-only hard kill (wrapper alive): freed in ~1.5 s via the normal child-wait path. Six kill variants on the probe daemon, no stuck lease in any. One observation from the probe: the attached PID is the engine process, not the wrapper, and in this build the live releases all came through the disconnect/child-wait paths — the reaper backstop is the defense for the wrapper-blind case and is covered by the broker unit tests. No stuck state to report.

  4. T-Crypt commented on Oct 21, 2026

    @T-Crypt
    Owner

    v0.3.3 is out with the reaper: https://github.com/T-Crypt/berth/releases/tag/v0.3.3. A taskkill /F /T on the run should now show lease.orphaned, lease.released and lease.freed in berth events within a few seconds.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions