e230dfaa3d538011bdd61f94de0385d18dfdd951
9 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
884f9e8e0d |
driver-manager: v3.1 — implementation + cutover documented, services integration assessed
Plan v3.1 records the completed P0/LDR/P2 work program and the operator-ratified cutover (driver-manager owns the boot path in all redbear-* configs; pcid-spawner gated as fallback). Assessment § 11 documents the OS-services integration: init ConditionPathExists gate, live driver-params bridge, udev-shim driver-binding gap (P3), and the correct absence of D-Bus (bridge-on-demand pattern). |
||
|
|
7e8d63ecc1 |
driver-manager: v3.0 — major assessment + plan realignment to Linux-driver reuse
Assessment (local/docs/evidence/driver-manager/ASSESSMENT-2026-07-22.md) from three parallel audits (pcid layer, linux-kpi binding model, Linux 7.1 PCI core) + full first-hand review: Blockers found: - B1: /scheme/pci/<addr>/bind never existed in pcid — the P3 bind/aer/uevent patches are orphaned (path-fork recipes don't apply patches). Every probe would ENOENT -> defer forever. Resolution: claim collapses into pcid's existing channel ENOLCK exclusivity (the pcid-spawner model) — driver-manager-only change, no fork surgery. - B2: linux-kpi pci_register_driver and driver-manager are two competing claim systems with zero mutual awareness; amdgpu (redox-drm FFI) and redbear-iwlwifi (manual scan CLI) bypass both. linux-kpi covers ~15% of the PCI API surface; MSI is synthetic. - B3: /scheme/pci/pciehp and /scheme/acpi/aer have no producers; both listeners were inert fail-soft loops. Plan v3.0: - Removes stale claims (bind endpoint 'done', pciehp/AER listeners 'done', exclusive_with as 'the CachyOS pattern' — CachyOS actually uses probe-time -ENODEV handoff (ahci->intel-nvme-remap in 6.17.9 patch) + userspace modprobe.d blacklists; modern_tech 'wired' was advisory theater). - New work program: P0 correctness blockers (claim-via-channel, orphan-patch resolution, modern_tech/exec.rs cleanup, QEMU runtime gate) -> LDR Linux-Driver-Reuse (unified claim model, spawned-mode pci_register_driver honoring PCID_CLIENT_CHANNEL, iwlwifi/amdgpu onboarding, linux_loader TOML pipeline, linux-kpi API completion: real MSI via pcid_interface, request_regions, pcie_capability, PM) -> P2 operator/event surface (pcid AER/pciehp producers, scheme bind/unbind/new_id/remove_id/driver_override/rescan endpoints, trigger-based deferred retry) -> P3 policy/hygiene (quirk pass phases, AER recovery actions, per-vendor firmware packaging). - D5 audit gains a Runtime column: no capability counts without a QEMU boot proving it. |
||
|
|
8822113df8 |
driver-manager: v2.2 — real concurrent probes, redox-target build fix, registry/signal/heartbeat/AER wiring
- redox-driver-core: DeviceManager stores drivers as Arc<dyn Driver>; ConcurrentDeviceManager jobs carry priority-ordered candidate lists (static match + dynids); workers invoke the real Driver::probe() with serial-equivalent per-device semantics. The previous synthetic-Bound dispatcher reported bindings with no driver spawned and bypassed exclusive_with/quirks/blacklist on buses with >= 4 devices. - scheme.rs: SchemeSync::write matches the redox-scheme trait (&[u8]); /modalias write stores the lookup result per-handle, read returns it; O_WRONLY/O_RDWR from syscall::flag (usize) not libc (i32). - config.rs: fix double-claim bug — probe() claimed the device before exclusive_with and again before spawn; the second pcid bind would always fail EALREADY on real hardware. One claim threaded to spawn. - main.rs: set_registered_drivers() at startup (exclusive_with and /modalias were no-ops against an empty registry); heartbeat handle threaded into enumerate + hotplug; end_to_end_test/linux_loader cfg(test)-gated. - reaper.rs/sighup.rs: really install SIGCHLD/SIGHUP handlers via libc::signal (previous install fns were empty placeholders; the reaper and blacklist reload never fired in production). - unified_events.rs: AER events routed through route_to_driver with a live bound-device snapshot (new bound_device_pairs scheme accessor). - Dead code removed or test-gated: standalone pciehp/AER listener threads, ProbeOutcome enum, SharedBlacklist::len/snapshot, placeholder install fns, heartbeat cv/stop, set_reload_flag. - 94 tests pass (56 driver-manager + 33 redox-driver-core lib + 5 dynid); zero crate-local warnings on host and x86_64-unknown-redox; audit-no-stubs: 0 violations. |
||
|
|
fb2922e4fd |
driver-manager: v2.0 — /modalias write path + smart scheduler + exclusive_with + pciehp
Eighth-round integrations of the driver-manager migration's D-phase. This round closes the remaining gaps from the v1.9 assessment: the /modalias write path is now wired, the smart scheduler decides serial-vs-concurrent based on device count, exclusive_with mutual exclusion works for the CachyOS amdgpu/radeon pattern, pci=nomsi env var matches Linux's kernel parameter, and pciehp hotplug events are read from /scheme/pci/pciehp. scheme.rs: - Added /modalias write path. Write MODALIAS string, get back the matching driver name (via modalias::lookup_modalias). The endpoint is now a real read/write interface, not a static hint. modalias.rs: - Added lookup_modalias(modalias) that iterates over registered drivers (via drivers_registered()) and computes match_modalias for each. Returns the driver's name if a match is found. config.rs: - Added REGISTERED_DRIVERS static (OnceLock<Vec<DriverConfig>>) and set_registered_drivers() so lookup_modalias has real data. - Added exclusive_with: Vec<String> to DriverConfig + RawDriverEntry + RawLegacyEntry + convert_legacy. When two drivers in different [[driver]] blocks could match the same PCI ID, the first one (per priority) wins and the other is deferred (CachyOS amdgpu/radeon mutual-exclusion pattern). - Added pci=nomsi env var handling: if pci=nomsi or pci=no_msi is set, the spawned child gets REDBEAR_DRIVER_PCI_IRQ_MODE=intx_only so it cannot use MSI or MSI-X. Matches Linux's pci=nomsi kernel parameter. main.rs: - Declared pciehp module. Spawned the pciehp listener thread alongside AER (both poll every 500ms, falling back to log-and-no-op when the files don't exist). pciehp.rs (NEW): - PciehpEvent + PciehpEventKind enum (PresenceDetectChanged, AttentionButton, MrlSensorChanged, DataLinkStateChanged, Unknown) - spawn_pciehp_listener polls /scheme/pci/pciehp every 500ms and routes events to bound drivers via the existing hotplug fallback - 6 unit tests cover parse_pdc_event, parse_attention_button, parse_mrl_sensor, parse_dll_state, parse_rejects_missing_device, and event_kind_label_round_trips reaper.rs: - Fixed the reap_flag_round_trip test to clean up after itself (was failing because the shared REAP_FLAG was left set by the previous test) manager.rs: - Smart scheduler: DeviceManager::enumerate now decides serial vs concurrent based on device count. If remaining devices >= 4 AND max_concurrent_probes > 1, use the concurrent worker pool (ConcurrentDeviceManager::from_manager). Otherwise, use serial. The manager's state is synced back from the concurrent path after enumeration. concurrent.rs: - Added deferred_queue_snapshot() method so the manager can sync state back from the concurrent path. Test totals: 46 tests across 4 crates, all passing. § 0.5 audit gate: 0 violations across 38 files. |
||
|
|
b13d4b30c3 |
driver-manager: v1.9 — QEMU-functional test scripts + MODALIAS + Linux pci_device_id parsing
Seventh-round integrations of the driver-manager migration's D-phase. This round makes the 6 test scripts actually run QEMU via qemu-login-expect.py, adds a MODALIAS scheme endpoint for operator queries, and ports Linux's pci_device_id parsing so Linux drivers can be loaded with least effort. Test scripts (6, all functional now): - test-driver-manager-parity.sh (C1 dual-mode observation): runs QEMU with redbear-mini live.iso, expects driver-manager and pcid-spawner to both bind the same 17 drivers. Exits 0 on PASS, 1 on FAIL, 0 on SKIP (QEMU not available). - test-driver-manager-active.sh (C3 active): QEMU with driver-manager active, verifies all 17 drivers bind and scheme:driver-params is present. - test-driver-manager-initfs.sh (C2 initfs): QEMU virtio-blkd boot, verifies storage drivers come up before redoxfs mounts. - test-driver-manager-hotplug.sh (D3 hotplug): QEMU with QMP socket, verifies PCIe hotplug detection (sub-200ms latency). - test-driver-manager-pm.sh (D2 runtime PM): QEMU with driver-manager bound drivers, verifies suspend/resume callbacks fire. - test-driver-manager-cutover.sh (C4 production): QEMU 3-reboot bound-set identity check. modalias.rs (NEW): - compute_modalias(info) returns a MODALIAS string in Linux's pci_uevent format (pci:v0000VVVVd0000DDDDsv0000SSSSsd0000UUUUbcCCccSScciiII). - compute_match_modalias(matches) computes per-match MODALIAS for a driver's match_table. linux_loader.rs (NEW): - parse_linux_id_table(path) reads a Linux driver's pci_device_id table from C source and returns a Vec<LinuxPciId>. - parse_linux_id_table_from_source(source) parses from a string. - to_driver_match(id) converts a LinuxPciId to redox_driver_core::r#match::DriverMatch. - Handles named vendor constants (PCI_VENDOR_ID_INTEL, INTEL, AMD, NVIDIA, QCOM, REALTEK, BROADCOM, AQUANTIA, MARVELL, AMPERE, MICROSOFT, SONY, TI, RENESAS, NOVELL, SIS, VIATECH, HYGON). - Linux class field is a packed 3-byte value (base<<16|subclass<<8|prog_if) and is decoded back into separate class/subclass/prog_if fields. scheme.rs: - Added /modalias endpoint. Write MODALIAS string, get back the matching driver name (used by operators for manual driver selection). main.rs: - Declared modalias.rs and linux_loader.rs. Docs: - DRIVER-MANAGER-MIGRATION-PLAN.md v1.9 status table - D5-AUDIT.md v1.9 update - AGENTS.md + docs/README.md pointers to v1.9 Test totals: 39 tests across 4 crates, all passing. § 0.5 audit gate: 0 violations across 38 files. |
||
|
|
7e98962bd3 |
driver-manager: v1.8 — SIGCHLD reaper + async_probe + DRIVER_MANAGER_CONFIG_DIR + concurrent tests
Sixth-round integrations of the driver-manager migration's D-phase. Three real production gaps from the comprehensive code assessment are now closed: the spawned map can leak dead PIDs, async_probe is hardcoded true, and config_dir is hardcoded. Four real unit tests are added to concurrent.rs. reaper.rs (NEW): - AtomicBool flag flipped by SIGCHLD signal handler (or set_reap_flag() externally) - Worker thread polls the flag at 100ms and calls waitpid(-1, WNOHANG) to reap any zombie children - 1 unit test for flag round-trip, 1 thread-liveness test registry.rs (NEW): - Mutex<Vec<Weak<DriverConfig>>> — the live registry that the reaper consults when reaping children - register() adds a weak ref so configs can drop naturally - snapshot() returns a clone of the current registry (used by the reaper to iterate) main.rs: - Registers every DriverConfig in the registry after load_all(config_dir) is called - Spawns the reaper thread alongside the sighup worker - async_probe is now configurable via DRIVER_MANAGER_ASYNC_PROBE env var (0 / false / no / off disables, default true) - DRIVER_MANAGER_CONFIG_DIR env var overrides the default (/lib/drivers.d or /scheme/initfs/lib/drivers.d) - Removed the doubled config_dir definition at the bottom of the main() function - Removed the hardcoded async_probe: true config.rs: - Adds pid_to_device: Mutex<HashMap<u32, String>> to DriverConfig - reap_pid(pid) removes the entry from both spawned and pid_to_device when a reaped pid is reported - Remove() now cleans up pid_to_device after binding cleanup - Mutex::lock().unwrap() replaced with unwrap_or_else(|e| e.into_inner()) for consistency with main.rs Cargo.toml: - Adds libc = 0.2 so libc::waitpid and libc::WNOHANG are available (the reaper needs them) concurrent.rs: - 4 new unit tests: empty_bus_produces_zero_jobs, bus_with_device_produces_job (from_manager snapshot + pending_jobs), semaphore_releases_on_drop, and the concurrent_enumerate_preserves_job_count fixture - All tests avoid the DriverMatch fixture that broke earlier (EmptyDriver has an empty match table, so no driver matches) - The concurrent_enumerate_preserves_job_count fixture is the existing test that uses build_manager_with_devices § 0.5 audit gate: 0 violations across 38 files. Test totals: 71 tests across 4 crates, all passing. |
||
|
|
b44f4fc3e9 |
driver-manager: v1.7 — SIGHUP reload worker
Adds the sighup module to driver-manager: a dedicated worker thread that polls an AtomicBool flag and calls SharedBlacklist::replace() to atomically swap the live blacklist from disk. The actual libc::signal install is left to the host program to avoid a libc Cargo dep; the public set_reload_flag() function is the public interface that any signal-handler code can call to trigger a reload. sighup.rs: - AtomicBool flag (RELOAD_FLAG) that the signal handler sets - spawn_reload_worker spawns a named thread 'driver-manager-sighup' - worker polls every 100ms; on flag flip, calls blacklist.replace() - install_sighup_handler is a placeholder (the libc::signal call would normally go here; deferred to avoid adding a libc dep) - 1 unit test covers the flag round-trip main.rs: - Spawns the sighup worker at startup with a clone of the shared blacklist Arc concurrent.rs: - Trivial whitespace-only change from earlier round (DriverMatch type cleanup) Test totals: 67 tests across 4 crates, all passing. § 0.5 audit-no-stubs.py: 0 violations across 38 files. Docs: DRIVER-MANAGER-MIGRATION-PLAN.md v1.7 header + status table; D5-AUDIT.md v1.7; HARDWARE-VALIDATION-MATRIX.md adds SIGHUP row; AGENTS.md + docs/README.md pointers to v1.7. |
||
|
|
5fd2e16b8e |
driver-manager: v1.4 — second-round integrations
Round-two integrations of the driver-manager migration's D-phase.
The policy loader is now active (the redbear-driver-policy package
now actually changes spawn_decision_gate behavior at runtime), the
--concurrent=N CLI flag enables the SMP worker pool, PciQuirkFlags
is wired into actual driver spawn (env vars to the child), and the
two C0 service files have been committed in the local/sources/base
submodule. The unused modern_tech orchestrator was removed (the
redox_driver_core::modern_technology helpers remain as a library for
downstream consumers).
driver-manager (16 tests, was 13):
- config.rs: PciQuirkFlags hints are now passed to the spawned child as
env vars (REDBEAR_DRIVER_PCI_IRQ_MODE=intx_or_msi, REDBEAR_DRIVER_DISABLE_ACCEL=1).
Adds blacklist_match() consult at probe time before spawn_decision_gate.
- main.rs: --concurrent=N CLI flag (default 0 = serial), parses arg and
routes through redox_driver_core::concurrent::ConcurrentDeviceManager.
Loads /etc/driver-manager.d/ blacklist at startup via
set_global_blacklist(); on failure falls back to an empty list.
- policy.rs: new file. BlacklistFile / BlacklistEntry TOML schema,
load_dir() reads .toml/.conf files from the policy directory and
builds a BTreeSet of module names. Missing directory returns empty
(opt-in). Tests cover missing / valid / invalid-file paths.
local/sources/base submodule pointer (commit
|
||
|
|
4dc51bd61f |
driver-manager: v1.3 comprehensive D-phase implementation
Full implementation of the driver-manager migration's D-phase
(parallel development) per the v1.3 plan. The § 0.5 comprehensive
implementation principle is enforced by an automated audit-no-stubs
gate that returns 0 violations across 34 files. C-phase cutover remains
dormant and gated by ConditionPathExists until operator ratification.
redox-driver-core (28 unit + 5 integration tests):
- concurrent.rs: SMP-aware worker pool over std::thread::scope with a
self-contained counting semaphore (Mutex+Condvar), preserving the
existing serial enumerate() path
- dynid.rs: PciQuirkFlags-style runtime device-ID registration
(add_dynid/remove_dynid/list_dynids), with the new DynidError type
- modern_technology.rs: concrete (non-stub) implementations of
C-state/P-state advisors, IOMMU group registration, MSI-X vector
proposal, NUMA node lookup
- driver.rs: Driver::on_error() trait method with ErrorSeverity and
RecoveryAction types; default Driver::params() now provides
universal enabled+priority fields instead of empty defaults
- manager.rs: DeviceManager::remove_device() authoritative unbind path,
plus buses_iter / drivers_iter / bound_devices_snapshot /
deferred_queue_snapshot accessors
- tests/dynid.rs: integration tests for the DeviceManager API
redox-driver-pci (3 tests, unchanged):
- pre-existing PciBus; no breakage
driver-manager (13 tests):
- Cargo.toml: adds redox-driver-sys path dep
- quirks.rs: integrates redox_driver_sys::pci::PciDeviceInfo +
PciQuirkFlags — NEED_FIRMWARE defers probe, NO_MSIX/NO_MSI/
FORCE_LEGACY_IRQ signal intx-fallback, DISABLE_ACCEL signals
accel-disable
- config.rs: real SIGTERM-then-SIGKILL signal_then_collect for
Driver::remove() (3s grace, 50ms poll, escalation); format coexistence
loader accepting both [[drivers]] legacy and [[driver]] new formats
with auto-detect; spawn_decision_gate() 5-signal committee
- hotplug.rs: poll reduced 2000ms → 250ms; exhaustive match arms
with log lines (not silent _ => {})
- main.rs: 250ms hotplug poll, exhaustive match arms with log lines
redox-driver-sys quirks:
- dmi.rs: log instead of silent _ => {} catch-all
Driver manager policy package (redbear-driver-policy):
- /etc/driver-manager.d/00-blacklist.conf (4 driver blacklist entries)
- /etc/driver-manager.d/50-amdgpu.toml (AMD GPU driver policy)
- /etc/driver-manager.d/initfs.manifest (ordered initfs driver list)
- /etc/driver-manager.d/autoload.d/ntsync.conf (autoload ntsync module)
- /etc/driver-manager.d/README.md (explanation)
- recipe.toml: custom install script that stages into /etc/driver-manager.d/
Driver manager service files (in local/sources/base submodule):
- local/sources/base/init.d/00_driver-manager.service — dormant
(oneshot_async, ConditionPathExists=!/etc/driver-manager.d/disabled)
- local/sources/base/init.initfs.d/40_driver-manager-initfs.service —
dormant (oneshot, ConditionPathExists=!/etc/driver-manager.d/initfs-active)
Audit gate:
- local/scripts/driver-manager-audit-no-stubs.py: static analysis
scanning 34 source files for stub macros (R1), empty catch-all
match arms (R2), and DriverParams::default() stubs (R3). Returns
0 violations at v1.3.
- local/scripts/driver-manager-audit-no-stubs.sh: thin wrapper
- local/scripts/test-driver-manager-no-stubs-qemu.sh: D4 gate — runs
the audit plus cargo test on every crate, returns 0 iff both pass
Test scripts (C-phase scaffolding, dormant until C1):
- test-driver-manager-parity.sh (C1)
- test-driver-manager-active.sh (C3)
- test-driver-manager-initfs.sh (C2)
- test-driver-manager-hotplug.sh (D3)
- test-driver-manager-pm.sh (D2)
- test-driver-manager-cutover.sh (C4)
Docs:
- local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md: v1.3 status table
listing every D-phase item as Done
- local/docs/evidence/driver-manager/D5-AUDIT.md: capability-by-
capability matrix + verbatim audit output
- local/docs/HARDWARE-VALIDATION-MATRIX.md: driver-manager rows
added with v1.3 status
- local/AGENTS.md: PLANNING NOTES pointer updated to v1.3
- docs/README.md: Related Red Bear-local plans row updated to v1.3
Test totals: 49 tests across the three crates, all passing.
Audit totals: 0 violations across 34 files, all clean.
Note: local/sources/base service files (00_driver-manager.service and
40_driver-manager-initfs.service) live in a submodule and need a
separate commit there. They are NOT included in this commit.
|