vm.go (1529 LOC) splits into vm_create, vm_lifecycle, vm_set, vm_stats, vm_disk, vm_authsync; firecracker/DNS/helpers stay in vm.go. guest_sessions.go (1266 LOC) splits into session_controller, session_lifecycle, session_attach, session_stream; scripts and helpers stay in guest_sessions.go. Mechanical move only. No behavior change. Adds doc.go and ARCHITECTURE.md capturing subsystem map and current lock ordering as the baseline for the upcoming subsystem extraction. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2.4 KiB
internal/daemon architecture
This document captures the current (pre-refactor) layout of the daemon
package and the lock ordering its callers must respect. It is the baseline
against which the phased split described in
~/.claude/plans/fluffy-seeking-teapot.md is executed.
Composition
Daemon is a single struct aggregating state for every subsystem:
- Layout, config, store, runner, logger, pid — infrastructure handles.
mu sync.Mutex— coarse lock, currently guards guest session controller map mutations and image registry mutations.vmLocks sync.Map— per-VM*sync.Mutex, one per VM ID.createOps,createOpsMu— in-flightvm createoperations.imageBuildOps,imageBuildOpsMu— in-flightimage buildoperations.tapPool,tapPoolNext,tapPoolMu— TAP interface pool.sessionControllers— active guest session controllers (guarded bymu).listener,webListener,webServer,webURL,vmDNS— networking.vmCaps— registered VM capability hooks.imageBuild,requestHandler,guestWaitForSSH,guestDial,waitForGuestSessionReady— injectable seams used by tests.
Lock ordering
Acquire in this order, release in reverse. Never acquire in the opposite direction.
vmLocks[id] → mu → {createOpsMu, imageBuildOpsMu, tapPoolMu}
Notes:
vmLocks[id]is the outer lock for any operation scoped to a single VM. Acquired viawithVMLockByID/withVMLockByRef.muis currently load-bearing for both session controller lookups and image registry changes. Holding it while calling into guest SSH is discouraged; prefer copying needed state out under the lock and releasing before blocking I/O.- The three subsystem locks (
createOpsMu,imageBuildOpsMu,tapPoolMu) are leaves. Nothing else is acquired while one is held.
The upcoming Phase 2 refactor will retire mu entirely by giving each
concern it currently guards its own owning type and lock. At that point
the ordering collapses to vmLocks[id] → subsystem-local lock.
External API
Only internal/cli imports this package. The surface is:
daemon.Open(ctx) (*Daemon, error)(*Daemon).Serve(ctx) error(*Daemon).Close() errordaemon.Doctor(...)— host diagnostics (no receiver).
All other *Daemon methods are reached only through the RPC dispatch
switch in daemon.go and are free to move/rename during refactoring.