Skip to main content

Module lock

Module lock 

Source
Expand description

The two host locks: one that keeps a second agent from reconciling the same policies, and one that serialises runtime creation.

03-control-flows.md, flow 3.1: “A single-instance lock prevents two agents on one host from reconciling the same policy.” Flow 2.4: the agent “takes the host-wide allocation lock before creating each local runtime”. 07-security.md’s threat table names the single-instance lock as one of the four controls on “API replay or a duplicate agent creates too many runners”.

§Why an operating-system file lock, and not a PID file

The requirement that decides the mechanism is “released on crash rather than leaking”. A PID file cannot do that: a process that is SIGKILLed, or whose machine loses power, leaves the file behind, and every recovery strategy built on top — is that PID still alive? was it reused? — is guesswork that fails exactly when it matters. An operating-system file lock is released by the kernel when the holding process ends, for any reason, with no cooperation from the process and nothing left to clean up.

Two mechanisms, one behaviour:

  • Windows opens the file for read and write while sharing only read access. A second acquirer asks for write access as well, which the holder’s share mode denies, and gets ERROR_SHARING_VIOLATION. A reader asks only for read access, which the share mode permits — which is what lets the loser find out who beat it.
  • Unix takes flock(LOCK_EX | LOCK_NB). flock is advisory and does not stand in the way of an ordinary open for reading, so the loser can read the holder record there too. Locks are held per open file description, so a second acquisition from the same process is refused as firmly as one from another process.

§The lock file is never deleted

Not on release, not on a clean shutdown, not by Drop. On Unix a lock is a property of the inode, so a holder that unlinks the file lets the next acquirer create and lock a different inode — after which two processes each hold “the lock” and neither can see the other. Leaving a zero-cost empty file behind is the whole price of not having that bug.

§What “host-wide” means, precisely

The lock is a file under crate::paths::AppPaths::state_dir, as 05-infrastructure.md specifies (“state/ agent lock”). Two agents contend if and only if they resolve the same state directory — which is what makes the lock host-wide for every configuration this product supports, and is worth stating rather than assuming: the platform-standard state directory is per-account on all three operating systems, so a daemon running as a service account and an interactive daemon run by a logged-in operator resolve different paths and would not contend. That is why 05-infrastructure.md requires service install to record its resolved configuration and why service status reports it. A future host-wide machine lock (%ProgramData%, /var/lock) would need the installer to create it with the right ownership, which is d3’s territory, not this module’s.

Structs§

HostLock
A held lock. Releasing it is dropping it.
LockHolder
Who holds a lock, as recorded by the holder itself.

Enums§

LockError
Something went wrong taking or inspecting a lock.
LockKind
Which of the two host locks.