1f58a3738c
Fourth-round integrations of the driver-manager migration's D-phase. Three new modules in driver-manager: heartbeat, aer, plus a SharedBlacklist wrapper around the existing Blacklist that supports live reload. heartbeat.rs: - Heartbeat struct with a publishing thread that writes a JSON status line to /var/run/driver-manager.heartbeat.json every 5s - Tracks bound / deferred / spawned / unbound / on_error counters - 3 unit tests cover counter updates, JSON output, and clone semantics aer.rs: - AER (PCI Express Advanced Error Reporting) listener thread - Reads /scheme/acpi/aer for events (parses severity + device bdf) - Routes to bound driver via scheme:driver-manager lookup - Returns RecoveryAction (Handled / ResetDevice / RescanBus) based on severity - Falls back to log-and-no-op when /scheme/acpi is absent - 7 unit tests cover parsing, routing, and severity mapping policy.rs: - Adds SharedBlacklist = Arc<RwLock<Blacklist>> + source_path - Supports live reload via replace() (re-reads from source_path) - is_blacklisted() takes a read lock (lock-free for the probe hot path) - set_global_shared_blacklist in config.rs wires it into the manager - 2 new unit tests cover replace() and snapshot isolation main.rs: - Spawns the heartbeat thread at startup (file at /var/run) - Constructs the SharedBlacklist from the policy directory config.rs: - Replaces GLOBAL_BLACKLIST OnceLock<Blacklist> with OnceLock<SharedBlacklist>; the probe hot path reads via Arc<RwLock>, not the OnceLock directly Docs: - DRIVER-MANAGER-MIGRATION-PLAN.md v1.6 status table (64 tests) - D5-AUDIT.md v1.6 update - HARDWARE-VALIDATION-MATRIX.md adds heartbeat and AER rows - AGENTS.md + docs/README.md pointers to v1.6 Test totals: 64 tests across 4 crates, all passing. § 0.5 audit-no-stubs.py: 0 violations across 37 files. SIGHUP trampoline for the SharedBlacklist is left for a future round; the replace() infrastructure is in place today so an operator can add the signal handler without changing the policy module.