Skip to content

Fix: clean up dnsmasq DHCP leases when destroying a ch VM - #1104

Merged
cdalar merged 1 commit into
mainfrom
fix/ch-dhcp-lease-cleanup-on-destroy
Sep 9, 2026
Merged

cdalar merged 1 commit into
mainfrom
fix/ch-dhcp-lease-cleanup-on-destroy

Conversation

@cdalar

@cdalar cdalar commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • DnsmasqDHCPManager.RemoveReservation removed a destroyed VM's DHCP hosts-file reservation but never its dnsmasq lease-file entry, since SIGHUP reloads the hosts file but never makes dnsmasq forget an already-granted lease.
  • Because chIPs allocates low addresses first, the very next ch VM to reuse a freed IP would get silently redirected to a different address by DHCP while onctl still believed it held the reserved one β€” create would hang until its SSH-wait timeout.
  • RemoveReservation now also strips the MAC's lease-file entry and restarts dnsmasq (persisting each bridge's cidr to a small state file so the restart doesn't need cidr threaded through the DHCPManager interface).

Found and reproduced live while wiring Windows/ch VM support into boxctl-vms: the very first Windows VM created through the new integration hung on this exact bug.

Test plan

  • go test ./internal/providerch/... β€” new regression tests TestDnsmasqDHCPManager_RemoveReservation_ClearsStaleLease / _NoMatch pass, existing TestDnsmasqDHCPManager_ReservationRoundTrip unaffected
  • go build ./..., go vet ./..., gofmt -l clean
  • Live-verified on aimax against a real cloud-hypervisor/dnsmasq/Windows Server 2025 guest chain: three consecutive create β†’ destroy β†’ create cycles reusing the same freed IP, each completing in ~20s with no SSH-wait timeouts (previously timed out every time)

πŸ€– Generated with Claude Code

DnsmasqDHCPManager.RemoveReservation only removed a VM's --dhcp-hostsfile
reservation on destroy, never its corresponding lease-file entry.
dnsmasq treats the lease file as its own in-memory-backed state (read
once at startup, then owned/rewritten by the running process) β€” SIGHUP
reloads the hosts file but never forgets an already-granted lease. Since
chIPs allocates low addresses first, the very next ch VM to reuse a
freshly freed IP would have its real DHCP handshake silently redirected
elsewhere, while onctl still believed it got the reserved address β€”
create would then hang until its SSH-wait timeout.

RemoveReservation now also strips the MAC's lease-file entry and
restarts dnsmasq (the only way to force it to forget an in-memory lease
without adding a new dhcp_release/dnsmasq-utils host dependency), using
a newly persisted per-bridge cidr file so the restart doesn't need cidr
threaded through the DHCPManager interface. Reproduced and verified live
on a real cloud-hypervisor/dnsmasq/Windows-guest chain: three consecutive
create/destroy/create cycles on the same freed IP, all completing in
~20s with no SSH-wait timeouts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012iVNj3mykz8m7QfuxWN3ae
@cdalar
cdalar merged commit 958f7cb into main Sep 9, 2026
12 checks passed
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.

1 participant

⌂ 捒网址