884f9e8e0d
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).
338 lines
23 KiB
Markdown
338 lines
23 KiB
Markdown
# Driver-Manager Migration — Major Assessment (2026-07-22)
|
||
|
||
**Scope:** implementation quality, plan viability, correctness, robustness,
|
||
AI-introduced code patterns, adjacent technology (pcid, pcid_interface,
|
||
redox-driver-pci, linux-kpi, redox-driver-sys, firmware-loader, redox-drm,
|
||
redbear-iwlwifi), gaps/blockers/inconsistencies.
|
||
**Cross-references:** Linux 7.1 (`local/reference/linux-7.1/`, commit
|
||
`ab9de95c9`), CachyOS (`local/reference/cachyos/` — linux-cachyos
|
||
`0001-cachyos-base-all.patch` 6.17.9 + desktop ISO 260628).
|
||
**Method:** three parallel codebase audits (pcid layer, linux-kpi binding
|
||
model, Linux 7.1 PCI core) plus a full first-hand review of every
|
||
driver-manager source file, the v2.2 warning/dead-code sweep, and the first
|
||
`x86_64-unknown-redox` cross-compile of the tree.
|
||
|
||
---
|
||
|
||
## 1. Executive verdict
|
||
|
||
**The plan is viable. The implementation is compile-grade solid after v2.2 —
|
||
and runtime-dead at three points that no amount of unit testing was ever
|
||
going to catch.** The single most important finding: driver-manager's claim
|
||
model assumes a pcid `/bind` endpoint that **does not exist** in the running
|
||
system, so on real hardware every probe defers forever and nothing binds.
|
||
The second: the stated critical goal — *reuse Linux drivers* — is currently
|
||
served by **two competing PCI claim systems with zero mutual awareness**
|
||
(driver-manager vs linux-kpi), and the two actual Linux-driver ports
|
||
(amdgpu, iwlwifi) bypass *both* of them. The third: the pciehp and AER
|
||
listeners poll files no producer creates.
|
||
|
||
All three are fixable with bounded work, and the fixes are now the top of
|
||
the plan (§ 9). None of them invalidates the architecture — the D-phase
|
||
foundation (DeviceManager, dynids, deferred probe, policy, quirks) is
|
||
well-shaped and matches Linux 7.1 semantics where it matters.
|
||
|
||
---
|
||
|
||
## 2. Blockers (severity-ranked)
|
||
|
||
### B1 — RUNTIME BLOCKER: `/scheme/pci/<addr>/bind` does not exist
|
||
|
||
`driver-manager/src/config.rs::claim_pci_device()` opens
|
||
`/scheme/pci/<addr>/bind` and maps `EALREADY` → "already claimed".
|
||
The pcid fork (`local/sources/base/drivers/pcid/src/scheme.rs:59`) exposes
|
||
`DEVICE_CONTENTS = &["channel"]` — there is no `bind` entry, no
|
||
`Handle::Bind`, no binds map. The three patches that add it
|
||
(`local/patches/base/P3-pcid-bind-scheme.patch`,
|
||
`P3-pcid-aer-scheme.patch`, `P3-pcid-uevent-format-fix.patch`) are
|
||
**orphaned**: zero commits in `local/sources/base` history contain the
|
||
content, and the cookbook does not apply patches for `path =` fork
|
||
recipes. This also violates orphan-patch governance (AGENTS.md §
|
||
Orphan-Patch Supersession Decision Tree — these are bucket (c)
|
||
MISSING-UPSTREAM that were never resolved).
|
||
|
||
Runtime consequence: open fails `ENOENT` → falls into the `Deferred`
|
||
catch-all → the deferred queue retries every hotplug poll **forever**.
|
||
driver-manager would appear alive (heartbeat ticks, enumeration logs)
|
||
while binding nothing. Worse than a crash.
|
||
|
||
**Root design insight:** pcid's `channel` open is *already* exclusive —
|
||
a second open fails `ENOLCK` (`scheme.rs:396-398`). pcid-spawner never
|
||
needed a `/bind` endpoint; it opens the channel, calls `enable_device`,
|
||
and hands the fd to the child via `PCID_CLIENT_CHANNEL`. The v2.x
|
||
driver-manager invented a redundant claim endpoint, then opens the
|
||
channel *separately* for the child (two exclusivity mechanisms for one
|
||
job — and the source of the double-claim bug fixed in v2.2).
|
||
|
||
**Fix (chosen, in plan § P0):** collapse claim into the channel open —
|
||
`PciFunctionHandle::connect_by_path()` once, `ENOLCK` → "already
|
||
claimed → next candidate", `into_inner_fd()` → child env. Claim
|
||
lifetime == child lifetime == channel fd lifetime, which is exactly
|
||
correct, matches pcid-spawner's battle-tested model, and requires
|
||
**zero pcid fork changes**. The alternative (committing the orphaned
|
||
bind-scheme patch into `submodule/base`) was rejected: it adds a
|
||
second, redundant exclusivity mechanism to pcid.
|
||
|
||
### B2 — GOAL BLOCKER: two competing PCI claim systems, zero mutual awareness
|
||
|
||
For the stated goal *reuse Linux drivers*, the integration surface is
|
||
linux-kpi. Today (`linux-kpi/src/rust_impl/pci.rs:620`):
|
||
|
||
- `pci_register_driver` **self-enumerates** `/scheme/pci/` via
|
||
`redox_driver_sys`, matches the C `id_table`, and calls the C probe
|
||
**in-process, synchronously** — no `/bind` claim, no `PCID_CLIENT_CHANNEL`,
|
||
no awareness of driver-manager. driver-manager has zero references to
|
||
linux-kpi and vice versa (verified: grep both directions, zero hits).
|
||
- The two real Linux-driver ports bypass even that: **amdgpu** is loaded
|
||
in-process by redox-drm via FFI (`redox_pci_set_device_info` populates
|
||
a static `pci_dev`; `redox_glue.h` defines `module_init` as a no-op);
|
||
**redbear-iwlwifi** manually reads `/scheme/pci/*/config` in a CLI
|
||
(`--probe` etc.) and is spawned by nothing — no driver-manager config,
|
||
no pcid-spawner entry.
|
||
- linux-kpi covers roughly **15% of the PCI API surface** a real Linux
|
||
driver needs: no `pci_request_regions`/`pci_release_regions`, no
|
||
`pcie_capability_read/write_*`, no power-state APIs, no
|
||
`pci_reset_function`, and **synthetic MSI** (`allocate_vectors` just
|
||
indexes from `base_irq` instead of using
|
||
`pcid_interface::enable_feature(PciFeature::Msi/MsiX)`, which exists
|
||
and is real).
|
||
|
||
**Fix (plan § LDR — Linux-Driver-Reuse track):** one ownership model.
|
||
driver-manager owns enumeration, matching, policy, claiming, and
|
||
spawning — for native *and* Linux-port daemons alike. linux-kpi's
|
||
`pci_register_driver` gains a **spawned mode**: when
|
||
`PCID_CLIENT_CHANNEL` is present in the environment, skip enumeration,
|
||
wrap the granted channel, match only the device it was spawned for, and
|
||
call probe for exactly that device. The standalone self-enumeration mode
|
||
remains for CLI tools. TOML driver configs for Linux ports are generated
|
||
from the C `id_table` by the (currently test-only) `linux_loader`.
|
||
|
||
### B3 — SILENT DEAD FEATURES: no pciehp or AER producers
|
||
|
||
`unified_events.rs` polls `/scheme/pci/pciehp` and `/scheme/acpi/aer`
|
||
every 500 ms. Neither path is produced by anything in the tree (verified
|
||
across pcid and acpid sources). Both readers fail-soft on `!path.exists()`,
|
||
so the listener thread runs forever doing nothing — a feature that looks
|
||
wired and is inert. The orphaned `P3-pcid-aer-scheme.patch` would add
|
||
per-device AER register files (`/scheme/pci/<addr>/aer/*`) to pcid.
|
||
pciehp has no producer patch at all.
|
||
|
||
Mitigating factor: device add/remove is covered by the 250 ms hotplug
|
||
enumeration poll, which works against the real `/scheme/pci/` directory.
|
||
The listeners are enhancement-tier, but the plan must stop presenting
|
||
them as done.
|
||
|
||
---
|
||
|
||
## 3. Implementation quality by component
|
||
|
||
| Component | Grade | Evidence |
|
||
|---|---|---|
|
||
| `redox-driver-core` manager + dynids | A− | Real probe semantics, priority ordering, dynid add/remove/list with validation; v2.2 made the concurrent path invoke real `probe()` with serial-equivalent fallback. Caveat: concurrent path double-enumerates buses (once in `enumerate()`, once in `from_manager`). |
|
||
| driver-manager probe/spawn (`config.rs`) | B+ (was D) | v2.2 fixed the double-claim (would have been EALREADY-dead on hardware) and wired the driver registry (exclusive_with/modalias were no-ops). Claim model itself is B1 — redesign in plan. |
|
||
| Scheme server (`scheme.rs`) | B | Correct trait impl after v2.2; `/modalias` write→store→read round-trip is functional but unusual vs Linux (read-only modalias + driver_override). Missing operator surface (§ G4). |
|
||
| Policy/blacklist (`policy.rs`) | A− | Real TOML loading, live `SharedBlacklist::replace()`, and — after v2.2 — a *actually installed* SIGHUP handler. |
|
||
| Signal handling (reaper/sighup) | B+ (was F) | v2.2 replaced placeholder `install_*` stubs with real `libc::signal` installation. Before that, the reaper and reload never fired in production. |
|
||
| Hotplug (`hotplug.rs`) | B | Polling add/remove detection + deferred retry works against the real scheme dir; no event triggers (§ G5). |
|
||
| unified_events / aer / pciehp | D | Parsers are real; producers don't exist (B3). `route_to_driver` now logs a decided `RecoveryAction` but nothing consumes it. |
|
||
| Heartbeat | B+ | Counters wired into enumerate/hotplug in v2.2; publishes real numbers now. |
|
||
| `modern_tech.rs` | D | Advisory theater — see § 5. |
|
||
| `linux_loader.rs` | C | Solid `pci_device_id` parser (PCI_DEVICE/SUB/CLASS/VDEVICE + named vendors) but `#[cfg(test)]`-only; the id_table→TOML pipeline it exists for is unwired. |
|
||
| `exec.rs` | F | Dead `spawn_driver` carrying `#[allow(dead_code)]` — suppression, against the zero-warning discipline applied everywhere else in v2.2. Remove. |
|
||
| `linux-kpi` PCI layer | C− | Real where it exists (config R/W, DMA via `/scheme/memory/translation`, IRQ threads); tiny coverage (B2); synthetic MSI; dormant `pci_register_driver` with no claim integration. |
|
||
| `pcid` / `pcid_interface` | A− | Mature: ECAM/MCFG + CF8 fallback, channel exclusivity, MSI/MSI-X enablement, BAR mapping, env hints (`REDBEAR_DRIVER_PCI_IRQ_MODE` etc. consumed end-to-end). The strongest layer in the stack. |
|
||
|
||
---
|
||
|
||
## 4. Plan viability
|
||
|
||
The D-phase/C-phase structure is sound and the § 0.6 parallel-development
|
||
constraint (never enable before D5 ratifies, never delete pcid-spawner)
|
||
has been honored. What the plan got wrong:
|
||
|
||
1. **It marked capabilities "✅ Done" at compile grade that are broken at
|
||
runtime** — the `<addr>/bind` claim (plan lines 94/134/771/921/975),
|
||
the pciehp listener, and the AER listener are the three cases. The D5
|
||
audit needs an explicit *runtime* bar per capability (see § 9, P0-4).
|
||
2. **It never modeled linux-kpi as a second claim system** — the largest
|
||
architectural blind spot relative to the project's stated goal.
|
||
3. **It presented `exclusive_with` as "the CachyOS pattern."** CachyOS
|
||
actually solves two-drivers-one-device two ways: *probe-time* deferral
|
||
(the 6.17.9 patch makes ahci return `-ENODEV` on remapped-NVMe
|
||
controllers so `intel-nvme-remap` binds instead — direct validation of
|
||
our `NotSupported`→next-candidate semantics) and *userspace*
|
||
modprobe.d blacklists. Our match-time `exclusive_with` is a third,
|
||
complementary mechanism — a superset, not a port. The plan now says so.
|
||
4. **"8 QEMU-functional test scripts" was aspiration** — the scripts exist
|
||
and are functional, but no driver-manager QEMU boot has ever been run.
|
||
Runtime validation is now a hard gate (P0-4).
|
||
|
||
---
|
||
|
||
## 5. AI-introduced code patterns (the "strange code" hunt)
|
||
|
||
Patterns found across this session's review, most now fixed in v2.2:
|
||
|
||
1. **Fake concurrency (fixed v2.2).** `ConcurrentDeviceManager::run_probe`
|
||
returned synthetic `Bound` without probing — "parallelism" that
|
||
reported success while doing nothing, with a comment framing it as an
|
||
intentional "integration boundary."
|
||
2. **Placeholder installers (fixed v2.2).** `install_handler()` /
|
||
`install_sighup_handler()` with empty bodies and "delegated to the
|
||
host program" comments — delegation to nobody. The claimed reason
|
||
("avoids the libc dep") was false in the same file that calls
|
||
`libc::waitpid`.
|
||
3. **Advisory theater (open — plan P0-3).** `modern_tech.rs` emits
|
||
C-state/P-state "advisories" as hardcoded constants (`7` on every
|
||
bind, `4` on every unbind) into JSON files **nothing reads**, and
|
||
computes an MSI-X proposal at spawn that is logged and discarded
|
||
instead of handed to the driver. The module doc pre-emptively insists
|
||
"these are real implementations, not stubs" — mechanically true,
|
||
functionally decorative. `modern_tech_for_path(key)` ignores its
|
||
argument and returns a global.
|
||
4. **Suppressed dead code (open — plan P0-3).** `exec.rs::spawn_driver`
|
||
is uncalled and carries `#[allow(dead_code)]` — the one place a
|
||
warning was silenced instead of fixed, right after v2.2 removed every
|
||
other instance.
|
||
5. **Unwired registries (fixed v2.2).** `set_registered_drivers` existed
|
||
but was never called; the heartbeat counters existed but were never
|
||
incremented; `route_to_driver` existed but was never called. A
|
||
recurring shape: *plumbing without a faucet* — infrastructure built
|
||
"for later" with the final one-line wiring forgotten.
|
||
6. **Redundant invention (open — plan P0-1).** The `/bind` claim endpoint
|
||
duplicates exclusivity pcid already provides via `channel`/`ENOLCK` —
|
||
new abstraction designed against an assumed (never verified) platform
|
||
surface.
|
||
|
||
The meta-lesson for the plan: every one of these survived because
|
||
**verification stopped at compile + host unit tests**. The audit gate
|
||
(§ 0.5) catches stub-shaped text, not behavior-shaped fiction. P0-4 adds
|
||
the missing gate.
|
||
|
||
---
|
||
|
||
## 6. Adjacent technology assessment
|
||
|
||
| Layer | State | Interaction with driver-manager |
|
||
|---|---|---|
|
||
| **pcid** | Strong. ECAM+CF8, channel exclusivity (`ENOLCK`), per-device `config` + `channel`. | Enumeration source (via redox-driver-pci reading `<addr>/config`) and claim channel owner. Missing: `/bind` (unneeded after P0-1), AER/pciehp producers (P2). |
|
||
| **pcid_interface** | Strong. `PciFunctionHandle` channel protocol, `enable_device`, MSI/MSI-X enable, BAR map, env hints consumed end-to-end. | The correct claim+channel vehicle (P0-1 builds on it). |
|
||
| **redox-driver-pci** | Adequate. Directory+config-file enumeration feeding `DeviceInfo`. | driver-manager's bus. No hotplug push — polling only. |
|
||
| **redox-driver-sys** | Strong. Quirks tables (compiled + TOML + DMI), MMIO/IRQ wrappers. | Quirk flags flow into spawn env vars end-to-end. Two pre-existing warnings (unused `Once`, unused `vendor`). |
|
||
| **linux-kpi** | Partial (B2). Real DMA/IRQ/config; ~15% PCI API; synthetic MSI; dormant registration path. | **None today.** The LDR track makes it the Linux-port runtime under driver-manager's ownership. |
|
||
| **firmware-loader** | Present (`scheme:firmware`); linux-kpi `request_firmware` reads through it via the filesystem. | `NEED_FIRMWARE` quirk defers probes, but no firmware-arrival trigger exists (G5). |
|
||
| **redox-drm + amdgpu** | Works via in-process FFI; bypasses both claim systems. | Spawned as a driver-manager child (class 0x03). LDR-4 migrates amdgpu to the spawned-mode path. |
|
||
| **redbear-iwlwifi** | CLI tool, manual PCI scan, spawned by nothing. | LDR-3 gives it a driver-manager config and proper claim. |
|
||
| **pcid-spawner** | The incumbent. Simple, correct, proven: channel-exclusive claim, `enable_device`, env handoff. | The behavioral reference for P0-1; stays in-tree as the dormant fallback after cutover. |
|
||
|
||
---
|
||
|
||
## 7. Linux 7.1 cross-reference (divergence audit)
|
||
|
||
| Mechanism | Linux 7.1 (`local/reference/linux-7.1/`) | Red Bear today | Verdict |
|
||
|---|---|---|---|
|
||
| Match precedence | `driver_override` → **dynids first** → static id_table (`pci-driver.c:136-180`) | dynids ∪ static by driver priority; **no driver_override** | Aligned except G3 — add per-device override |
|
||
| Match "scoring" | None — first table entry wins; order = specificity (`pci.h pci_match_one_device`) | `priority` field on drivers | Superset; keep |
|
||
| Two drivers, one device | Probe-time `-ENODEV` handoff (CachyOS ahci→intel-nvme-remap) + modprobe.d blacklists | Match-time `exclusive_with` **plus** probe-time `NotSupported` fallback | Superset; aligned |
|
||
| Dynids | sysfs `new_id`/`remove_id`, dynids checked before static, `-EEXIST` on dup (`pci-driver.c:195-299`) | Library-only `add_dynid`/`remove_dynid` with validation; **no runtime surface** | G4 — expose via scheme |
|
||
| Deferred probe | pending/active lists, **trigger on any successful probe**, timeout with reasons (`dd.c:82-197`) | Queue + blind 250 ms poll retry | G5 — add success/scheme-arrival/firmware triggers |
|
||
| AER | `pci_error_handlers` state machine: error_detected → mmio_enabled → slot_reset → resume; 6-state `pci_ers_result` (`pcie/err.c:210-299`) | Parse + log + decide (unconsumed); no producer | B3 + P2: producer first, then recovery actions |
|
||
| pciehp | 5 event bits (ABP/PFD/PDC/DLLSC/CC), ISR→IST, two-phase presence handler (`pciehp_hpc.c:623-798`) | Parser for the same taxonomy; no producer | B3 + P2 |
|
||
| `pci=nomsi` | Global `pci_msi_enable=false`, which also **gates AER** (`msi.c:985`, `aer.c:138`) | Per-spawn `REDBEAR_DRIVER_PCI_IRQ_MODE` env | Per-device model is finer; keep |
|
||
| Quirks | 500 `DECLARE_PCI_FIXUP_*` across **8 pass phases** (early…suspend_late) | TOML + compiled + DMI, bind-time only | Directionally superior; add early/runtime phase split (P3) |
|
||
| Autoloading | uevent `MODALIAS` → kmod → `modules.alias` (`pci-driver.c:1587-1617`) | Poll → match_table/dynids; `/modalias` scheme = operator lookup | Aligned; document the mapping |
|
||
| Operator surface | per-driver `bind`/`unbind`/`new_id`/`remove_id`, per-device `driver_override`/`rescan`/`remove` | `/devices`, `/bound`, `/events`, `/modalias` only | G4 — add the write endpoints |
|
||
|
||
---
|
||
|
||
## 8. CachyOS cross-reference
|
||
|
||
Source: `local/reference/cachyos/linux-cachyos/0001-cachyos-base-all.patch`
|
||
(6.17.9, 6 patches: asus/bbr3/block/cachy/fixes/t2) +
|
||
`iso/cachyos-desktop-linux-260628.pkgs.txt`.
|
||
|
||
1. **CachyOS does not redesign driver loading.** Its PCI-relevant kernel
|
||
changes are targeted tuning: the ahci→intel-nvme-remap probe handoff
|
||
(`-ENODEV`), `pci_real_dma_dev` for the NVMe-remap bus, AMD Zen5 init,
|
||
i915 PSR fixes. This validates our approach: mirror Linux 7.1
|
||
semantics, deviate only where the microkernel forces it.
|
||
2. **The ahci handoff is the canonical two-driver pattern** and it is
|
||
*probe-time*, not match-time — direct external validation that our
|
||
per-device candidate fallback (fixed into the concurrent path in
|
||
v2.2) models reality. `exclusive_with` remains useful for the
|
||
amdgpu/radeon class of *userspace policy* conflicts, which CachyOS
|
||
handles in modprobe.d — our `/etc/driver-manager.d` blacklist is the
|
||
same layer.
|
||
3. **Firmware packaging is per-vendor granular** (`linux-firmware-amdgpu`,
|
||
`-intel`, `-realtek`, `-radeon`, …) — the model for our
|
||
`fetch-firmware.sh` subsets and future firmware-loader packaging (P3).
|
||
4. **Bootstrap drivers live in the initramfs** (mkinitcpio 41-5) loaded
|
||
via udev/modprobe `$MODALIAS`. Our analog is `driver-manager
|
||
--initfs` + the initfs driver configs — the correct mapping, and the
|
||
path that C-phase runtime validation must exercise first.
|
||
5. `amd-ucode`/`intel-ucode` ship as separate packages — CPU microcode
|
||
loading is a separate pipeline (out of driver-manager scope; noted
|
||
for the firmware track).
|
||
6. No `modprobed-db` in this ISO's package list (CachyOS's
|
||
module-trimming tool); `kmod 34.2` present.
|
||
|
||
---
|
||
|
||
## 9. Findings register (severity-ordered)
|
||
|
||
| # | Severity | Finding | Plan item |
|
||
|---|---|---|---|
|
||
| B1 | Blocker | `/bind` endpoint absent; claim model runtime-dead | P0-1 (claim-via-channel) |
|
||
| B2 | Goal-blocker | linux-kpi vs driver-manager: two claim systems, zero awareness; ~15% API; synthetic MSI | LDR-1…LDR-5 |
|
||
| B3 | High | pciehp/AER producers absent; listeners inert | P0-2 (restate), P2-1 (producers) |
|
||
| G1 | High | Orphaned P3 patches in `local/patches/base/` (bind/aer/uevent) violate orphan governance | P0-2 (decision-tree resolution) |
|
||
| G2 | High | Zero runtime validation at any layer; D5 "Done" claims are compile-grade | P0-4 (runtime gate) |
|
||
| G3 | Medium | No `driver_override` equivalent (Linux Tier-1) | P2-2 |
|
||
| G4 | Medium | dynids library-only; no `/new_id` `/remove_id` `/bind` `/unbind` `/rescan` scheme surface | P2-2 |
|
||
| G5 | Medium | Deferred retry is blind polling; no success/scheme-arrival/firmware-arrival triggers | P2-3 |
|
||
| G6 | Medium | `modern_tech` advisory theater; msix proposal discarded | P0-3 (strip to honest core) |
|
||
| G7 | Low | `exec.rs` dead code with `#[allow(dead_code)]` | P0-3 (delete) |
|
||
| G8 | Low | Concurrent path double-enumerates buses | P3 (fold enumeration into dispatcher) |
|
||
| G9 | Low | redbear-iwlwifi unspawned; amdgpu bypasses both models | LDR-3, LDR-4 |
|
||
| G10 | Low | Pre-existing warnings in libredox/pcid/redox-driver-sys; stale `redox-driver-core/src/` duplicate tree | P3 hygiene |
|
||
|
||
---
|
||
|
||
## 10. What is genuinely good
|
||
|
||
Worth stating plainly, because the register above is necessarily harsh:
|
||
|
||
- The **D-phase skeleton is right**: DeviceManager/dynids/deferred-probe/
|
||
policy/quirks map cleanly onto Linux 7.1's driver core, and where Red
|
||
Bear deviates (per-device IRQ-mode env, TOML+DMI quirks, priority
|
||
field) the deviations are defensible or superior.
|
||
- **pcid + pcid_interface are production-quality** — the layer everything
|
||
else stands on is the strongest part of the stack.
|
||
- The **v2.2 sweep** (this session) removed an entire class of fiction:
|
||
fake concurrency, placeholder signal handlers, dead registries, the
|
||
double-claim. The tree after v2.2 is honest at compile grade.
|
||
- The **§ 0.6 constraint held**: none of the runtime-dead code ever
|
||
shipped in a boot path. The process worked; the audit just came one
|
||
gate later than it should have — hence P0-4.
|
||
|
||
*Plan updates implementing this register: `../../DRIVER-MANAGER-MIGRATION-PLAN.md` v3.0.*
|
||
|
||
---
|
||
|
||
## 11. OS-services integration assessment (added 2026-07-23, cutover round)
|
||
|
||
How driver-manager fits the wider OS service architecture — D-Bus, zbus,
|
||
udev-shim, driver-params, and the init system:
|
||
|
||
| Surface | State | Verdict |
|
||
|---|---|---|
|
||
| **init service model** | Fixed in this round. init learned `ConditionPathExists` (with `!` negation) — the C0 dormancy was previously a parser-rejection accident. Cutover wiring: driver-manager services run by default; pcid-spawner services are gated behind `/etc/driver-manager.d/disabled` as the operator fallback. | ✅ Correct and reversible |
|
||
| **driver-params daemon** | **Live integration, pre-existing and correct.** `driver-params` reads `/scheme/driver-manager/bound` (`read_driver_manager_bound`, tolerating ENODEV when the scheme is absent) and exposes `enabled=true` params per bound driver; driver-manager's `notify_bind` writes per-device params the other direction. | ✅ Working bridge |
|
||
| **udev-shim** | Reads `/scheme/pci` directly — the raw bus view, without driver-binding information. On Linux, libudev exposes `DRIVER=` and driver links; post-cutover udev-shim should also read `/scheme/driver-manager/{bound,devices}` so udisks/KDE-Solid-style consumers see bindings. | 🟡 Gap (P3, non-blocking) |
|
||
| **D-Bus / zbus** | driver-manager has no D-Bus presence, and that is **correct today**. The Linux analog: udev events feed domain daemons (udisks2, upower, NetworkManager) which own the D-Bus APIs — udev itself does not publish on the bus. Red Bear's scheme *is* the native device-event transport; a driver-manager D-Bus service now would duplicate the scheme for zero consumers. If a desktop consumer ever needs bind signals over D-Bus, the pattern is a thin zbus bridge daemon (same shape as `redbear-sessiond` for login1), not D-Bus code inside driver-manager. | ✅ Correctly absent; bridge only on demand |
|
||
| **redbear-dbus-services** | No activation entry needed (no bus name). | ✅ Nothing to do |
|
||
| **redox-drm / display stack** | Already convergent: honors the pcid handoff (`connect_default`), uses only non-exclusive config + MMIO access. | ✅ Verified |
|
||
| **initfs storage path** | `40_driver-manager-initfs.service` (oneshot, `--initfs`) is default-on; pcid-spawner-initfs gated as fallback. The initfs driver-manager exits after enumeration (oneshot) — correct for the pre-switchroot phase. | ✅ Wired; first QEMU gate target |
|
||
|
||
*Cutover commits: `e30f2499` (init gate), `c72d4247` (service gates), `b338760111` + parent bumps (config cutover).*
|