103 lines
6.7 KiB
Markdown
103 lines
6.7 KiB
Markdown
# STEP20C — headless allocator triage
|
|
|
|
Status: **EXPERIMENTAL / PRISTINE_ALLOCATOR_BLOCKED / CORE_NOT_RUN**.
|
|
This is a source-based triage of the [V5 native failure](STEP20C_HEADLESS_BOOT_GATE2.md),
|
|
not a renderer repair or a new native authorization. STEP20C remains NEXT;
|
|
production multi-output NOT_YET_SUPPORTED. No compositor, build, IPC, device,
|
|
scope or production change is authorized by this note.
|
|
|
|
## Observed result and source boundary
|
|
|
|
The single approved V5 pristine run failed after 0.361879 seconds, before
|
|
private IPC, with oracle null. Its first allocator error was ENOENT opening
|
|
`/dev/udmabuf` in the private `/dev`; allocator creation then failed.
|
|
CORE has no ATTEMPT and is CORE_NOT_RUN. The preceding Mesa software-rendering
|
|
warning is not established as fatal. No effective renderer/backend capability
|
|
masks, EGL provider or selected native device identity were recorded.
|
|
|
|
Static inspection used pristine source archives without `.git`, at these
|
|
retained pins. Twelve inspected SceneFX/wlroots files match the corresponding
|
|
Git commit objects; this proves neither binary reproducibility nor live capabilities:
|
|
|
|
- [SwayFX fd71a6bdc061bd633b488ae7b83e8a6981d22f86](https://github.com/wlrfx/swayfx/blob/fd71a6bdc061bd633b488ae7b83e8a6981d22f86/sway/server.c#L283):
|
|
`server.c:283` directly calls `fx_renderer_create`; `:305` calls the allocator.
|
|
- [SceneFX 37ccd723bef49e6891156ffafce8f549f01446cc](https://github.com/wlrfx/scenefx/tree/37ccd723bef49e6891156ffafce8f549f01446cc):
|
|
`render/fx_renderer/{util.c,fx_renderer.c,fx_framebuffer.c,fx_offscreen_buffers.c}`
|
|
and `render/egl.c` govern the FX path described below.
|
|
- [wlroots d783533489e1f75d6886c2ab5c5960090ef268f8](https://gitlab.freedesktop.org/wlroots/wlroots/-/tree/d783533489e1f75d6886c2ab5c5960090ef268f8):
|
|
`render/allocator/{allocator.c,shm.c,udmabuf.c}`, `render/pixman/renderer.c`,
|
|
`util/shm.c` and `backend/{headless,multi}/backend.c` govern selection.
|
|
|
|
## Allocation contract inferred from those sources
|
|
|
|
`open_preferred_drm_fd` honors `WLR_RENDERER_FORCE_SOFTWARE=1` before render-node
|
|
selection, preserving FD -1 on this creation path. SceneFX then calls
|
|
`wlr_egl_create_with_drm_fd`; its negative-FD path selects an EGL device with
|
|
`EGL_MESA_device_software` and allows software. GBM fallback requires FD >= 0.
|
|
This explains the intended software route, not the effective V5 EGL identity.
|
|
|
|
`fx_renderer_create_egl` initializes `render_buffer_caps` to DMABUF only.
|
|
SHM/DATA_PTR texture import is a separate capability, not SHM render-target
|
|
support. `fx_framebuffer.c:138` rejects targets without `wlr_buffer_get_dmabuf`.
|
|
Headless advertises DMABUF, SHM and DATA_PTR; the multi backend intersects
|
|
capabilities of presenting backends. Actual V5 masks remain unmeasured.
|
|
|
|
Allocator predicates test **nonempty bit intersections**, not containment of
|
|
all bits in a combined mask. In source order, with B = backend caps,
|
|
R = renderer render-buffer caps, D = selected allocator DRM FD:
|
|
|
|
| Candidate | Eligibility predicate, before compiled-feature/create failures |
|
|
| --- | --- |
|
|
| GBM | `(B & DMABUF) && (R & DMABUF) && D >= 0` |
|
|
| SHM | `(B & (SHM \| DATA_PTR)) && (R & (SHM \| DATA_PTR))` |
|
|
| DRM dumb | `(B & (DMABUF \| DATA_PTR)) && (R & (DMABUF \| DATA_PTR)) && D >= 0 && drmIsMaster(D)` |
|
|
| UDMABUF | `(B & (DMABUF \| SHM)) && (R & (DMABUF \| SHM)) && D < 0` |
|
|
|
|
Thus headless + FX DMABUF-only + negative FD skips SHM and reaches UDMABUF
|
|
when compiled in. `udmabuf.c:146` opens `/dev/udmabuf` with `O_RDWR | O_CLOEXEC`.
|
|
That source path is consistent with the observed failure; it is not a runtime
|
|
capture of every predicate. Host metadata reports root:kvm mode0660 and the
|
|
user outside kvm. Metadata grants no authority to open or expose the device,
|
|
change permissions/group membership, or broaden the sandbox.
|
|
|
|
## Decision matrix
|
|
|
|
| Route | Evidence | Hypothesis / future test | Risk / disposition |
|
|
| --- | --- | --- | --- |
|
|
| Existing software FX | Negative-FD EGL route; DMABUF render targets; UDMABUF ENOENT observed | Measure provider, FD and format/capability sets in a separately approved FX-only helper | Software EGL alone does not supply a compatible allocator; BLOCKED |
|
|
| Pixman + SHM | Pixman advertises DATA_PTR; SHM allocator uses `shm_open`, unlink, `ftruncate`, `mmap` | A writable private `/dev/shm` could serve this distinct allocator route without a physical device | No FX compatibility proof; not a substitute pristine control |
|
|
| `WLR_RENDERER=pixman` alone | SwayFX directly creates SceneFX; `fx_get_renderer` asserts FX, including offscreen buffers | Any private renderer/compositor change needs a separate design and approval | Environment override cannot replace this FX contract |
|
|
| Host UDMABUF / DRM | Device-opening source requirement; no approved exposure | No device experiment proposed here | Sandbox expansion excluded; no workaround promised |
|
|
|
|
## Smallest next experiment to authorize
|
|
|
|
Offline validation passes eight cases executing the verbatim allocator-selection
|
|
function compiled as C17 with inert callees, plus six static FX/Pixman/call-site/
|
|
framebuffer assertions. No device was opened and no EGL was initialized. These
|
|
checks validate source selection, not effective EGL identity or target allocation.
|
|
|
|
The next runtime decision would require a **new explicit approval** for one
|
|
small EGL/FX-only helper, without compositor, IPC, systemd scope or host-device
|
|
exposure. Before execution, review exact pinned sources/library identities,
|
|
helper code, fixed deadline, output/resource bounds and cleanup. Use fresh
|
|
private temporary/runtime storage and private `/dev/shm`; never reuse a V5 LAB
|
|
or reservation. Record EGL provider/software-device identity, FD < 0,
|
|
backend/render/texture caps and render-target formats; refuse device fallback,
|
|
missing identity or incompatible allocation. No retries or automatic escalation.
|
|
|
|
This helper is a proposal, NOT_RUN: measuring EGL identity/caps/formats cannot
|
|
resolve an absent allocator and would not qualify boot, rendering or CORE. If it finds no compatible allocation under the existing containment,
|
|
retain PRISTINE_ALLOCATOR_BLOCKED / CORE_NOT_RUN and report the limitation;
|
|
any renderer or sandbox design change needs its own scoped decision.
|
|
|
|
|
|
## EGL/FX follow-up — 2026-10-17
|
|
|
|
The [single EGL/FX attempt](STEP20C_HEADLESS_EGL_FX_PROBE.md#observed-single-attempt--2026-10-17)
|
|
consumed its reservation but failed at Bubblewrap namespace creation before the
|
|
helper. EGL_NOT_RUN / ALLOCATOR_NOT_ATTEMPTED: it supplies no new allocator or
|
|
renderer evidence and leaves V5 PRISTINE_ALLOCATOR_BLOCKED / CORE_NOT_RUN intact.
|
|
The [task-limit design](STEP20C_EGL_FX_TASK_LIMIT_PROTOCOL.md) is offline only;
|
|
its proposed cgroup/scope is a new protocol, not authorized by the older
|
|
scope-free proposal above. New qualification and EGL execution need separate
|
|
approvals. Historical LABs and raw verdicts remain immutable.
|