feat(drm): add GPU exclusion policy - #106
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The fail-closed DRM-policy detection on TOML parse errors should also fail closed when the file cannot be opened/read, otherwise a requested DRM policy could be silently discarded.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds an opt-in native-session DRM “policy” to control which physical GPU Umbriel renders on and to exclude specified GPUs from being opened/enumerated, including a GBM-only renderer path in the vendored umbrielfx to avoid hidden EGL multi-GPU probing.
Changes:
- Introduce
BackendManager+drm_policyhelpers to enumerate/allow/exclude GPUs before wlroots opens KMS devices, and to audit open device FDs. - Extend config loading/diagnostics to parse
[drm]selectors and fail closed when a requested DRM policy could otherwise be discarded. - Add unit/integration tests and documentation for the DRM policy, plus build/dependency updates (libudev, wlroots feature checks).
File summaries
| File | Description |
|---|---|
| umbrielfx/tests/renderer.c | Adds a renderer/FD-stability test for renderer identity and descriptor ownership. |
| umbrielfx/render/fx_renderer/fx_renderer.c | Adds GBM-only renderer creation path and closes owned DRM FD earlier. |
| umbrielfx/render/egl.c | Adds GBM-exact EGL init path and DRM FD duplication strategy for strict device selection. |
| umbrielfx/meson.build | Builds and registers the new umbrielfx-renderer-test. |
| umbrielfx/internal/render/egl.h | Extends internal wlr_egl struct with DRM FD strategy + new GBM-only API. |
| umbrielfx/include/umbrielfx/render/fx_renderer/fx_renderer.h | Exposes fx_renderer_create_with_drm_fd_gbm() in the public header. |
| tests/unit/drm_policy.cpp | Adds unit tests for physical GPU identity, exclusions, backend env parsing, and reconciliation planning. |
| tests/unit/config_watcher.cpp | Updates tests to assert ConfigStore::load() success. |
| tests/unit/config_load.cpp | Adds [drm] config parsing tests and adjusts environment-variable parsing expectations. |
| tests/unit/config_change.cpp | Ensures [drm] changes are detected and summarized as restart-required. |
| tests/meson.build | Registers the new drm-policy unit test. |
| tests/harness/verify.sh | Unsets WLR_DRM_DEVICES in harness to avoid mixed-vendor selector issues. |
| src/wlr.h | Includes wlroots DRM backend header for new DRM interactions. |
| src/server/server.h | Stores BackendManager in Server for lifecycle ownership. |
| src/server/server.cpp | Routes backend/session/renderer creation through BackendManager and audits devices post-allocator. |
| src/server/server_events.cpp | Warns on DRM config reload (restart required) and uses BackendManager during renderer recovery. |
| src/server/drm_policy.h | Defines identities/matching/planning APIs for DRM selection/exclusion. |
| src/server/drm_policy.cpp | Implements GPU identity matching, exclusions, NVIDIA parsing helpers, and reconciliation planning. |
| src/server/backend_manager.h | Declares the BackendManager boundary for backend selection + renderer creation. |
| src/server/backend_manager.cpp | Implements filtered udev-based DRM enumeration, exclusion enforcement, hotplug reconciliation, and FD audits. |
| src/main.cpp | Makes startup fatal on invalid initial config; keeps validate printing diagnostics. |
| src/config/store.h | Changes ConfigStore::load() to return bool and documents DRM fail-closed behavior. |
| src/config/config.h | Adds Config::Drm and makes loadConfig() return bool. |
| src/config/config.cpp | Parses [drm] config keys, normalizes PCI addresses, and enforces fail-closed semantics for requested DRM policy. |
| src/config/config_merge.h | Tracks whether a parse error may discard a DRM policy. |
| src/config/config_merge.cpp | Adds a structural TOML scanner to detect [drm] intent even when parsing fails. |
| src/config/change.h | Adds drm to config-change tracking. |
| src/config/change.cpp | Marks/configures drm change detection and summary rendering. |
| README.md | Documents libudev as a required dependency. |
| PACKAGING.md | Adds libudev to packaging requirements. |
| nix/package.nix | Adds systemd (for libudev) to Nix build inputs. |
| meson.build | Enforces wlroots build features + links libudev; wires in new server sources. |
| examples/config.toml | Adds commented example [drm] configuration. |
| docs/user/configuration.md | Documents [drm] keys, behavior, limits, and environment interactions. |
| docs/design/README.md | Adds design doc link for DRM device policy. |
| docs/design/drm-device-policy.md | New design doc detailing the filtering approach, lifecycle, and verification guidance. |
| docs/design/configuration-reload.md | Notes DRM policy is captured at startup and requires restart to apply changes. |
Review details
- Files reviewed: 37/37 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
e06bf6b to
afe495d
Compare
03b32a0 to
571f1ac
Compare
|
The description now contains the required template structure. |
9d13d1c to
2fe9062
Compare
2fe9062 to
20dc4f1
Compare
20dc4f1 to
b172ee0
Compare
|
Thanks |
Summary
Adds optional native GPU exclusions by DRM path or PCI address. Paths resolve once before any GPU opens; PCI selectors work while a GPU is absent or bound to
vfio-pci.BackendManagerfilters startup and hotplug, gives allowed GPUs independent backends, and uses an explicit GBM renderer constructor. Descriptor checks reject excluded devices, unidentified DRM descriptors, and unexpected inspection errors. NVIDIA metadata is needed only for open per-GPU devices without a PCI identity from udev. Configuration errors that could hide exclusions stop startup. Automatic discovery remains unchanged without exclusions and in nested or headless sessions. Policy changes require a restart.See the configuration reference for selectors and limits.
Motivation
Keep a guest GPU available for VFIO while Umbriel uses the remaining GPUs. Host tooling manages PCI driver binding.
Type of Change
Testing
just format,git diff --check, clang-tidy, documentation links, and validation ofexamples/config.tomlpassed.Three existing color-config test warnings remain. Physical VFIO transitions and multi-GPU display behavior were not tested.
Checklist
SCOPE.md, or its scope was agreed in an issue or on Discord first.CONTRIBUTING.md.just format, or this PR has no C++ changes.docs/andexamples/config.toml, or this PR does not change user-facing configuration or behavior.