e289904852
- STUBS-AUDIT-AND-REWRITE-PLAN.md: master plan, 20 drivers audited - USB-STUBS-AUDIT.md: USB stack focus, xhcid/usbhubd/usbctl/usbhidd/usbscsid/ucsid - HID-STUBS-AUDIT.md: HID focus, usbhidd/i2c-hidd/intel-thc-hidd/ps2d/inputd/evdevd - LOWLEVEL-STUBS-AUDIT.md: ACPI/PCI/IRQ/IOMMU/boot/init, 50+ row coverage - BOOT-AND-HW-ENABLEMENT-ASSESSMENT.md: kernel to display chain, NO VESA policy - DESKTOP-SERVICES-ASSESSMENT.md: D-Bus, session, audio, network - CONFIG-AND-INIT-ASSESSMENT.md: configs, init.d, recipes, layering - GPU-MESA-KDE-CHAIN-ASSESSMENT.md: Mesa to Plasma build chain These documents track the v6.0 stub-fix campaign and the comprehensive Phase 1-5 implementation work. All cited paths and line numbers are real. Documents are durable in local/docs/ which survives make distclean.
1573 lines
78 KiB
Markdown
1573 lines
78 KiB
Markdown
# Desktop Services Assessment — D-BUS, SESSION, AUDIO, NETWORK, SECURITY
|
||
|
||
**Generated:** 2026-06-09
|
||
**Scope:** All services between `pcid`/`driver-manager` and `sddm`/KDE that must be running,
|
||
correctly wired, and correctly sequenced on `redbear-full` to deliver a working Wayland login
|
||
prompt and a working KDE desktop on QEMU and bare metal.
|
||
**Companion to:** `CONSOLE-TO-KDE-DESKTOP-PLAN.md`, `DBUS-INTEGRATION-PLAN.md`,
|
||
`GREETER-LOGIN-IMPLEMENTATION-PLAN.md`, `WIFI-IMPLEMENTATION-PLAN.md`,
|
||
`USB-IMPLEMENTATION-PLAN.md`, `BLUETOOTH-IMPLEMENTATION-PLAN.md`.
|
||
|
||
This document is **audit only**. No source files are modified.
|
||
|
||
---
|
||
|
||
## Executive Summary
|
||
|
||
| Metric | Value |
|
||
|---|---|
|
||
| Recipes surveyed in `local/recipes/system/` | 47 |
|
||
| Total Rust LoC in the desktop-services chain (sessiond + authd + launch + greeter + wifictl + netctl + info + polkit + upower + udisks + notifications + statusnotifier + audiod + dhcpd + netstack) | ~16,000 LoC |
|
||
| Recipes with `#TODO` first-line header in `recipe.toml` | 5 (dbus, redbear-polkit, redbear-upower, redbear-udisks, redbear-notifications) |
|
||
| Stubs / no-op returns in `redbear-sessiond` `Manager` | 7 (all `can_*` power methods) |
|
||
| Stubs / no-op returns in `redbear-sessiond` `Session` | 2 (`kill`) |
|
||
| Stub backend in `redbear-wifictl` (`StubBackend`) | real, used when no driver present |
|
||
| No-op no-op service definitions (`cmd = "echo ... skipped"`) | 1 (seatd on `redbear-mini`) |
|
||
| `*Stub` types / `*stub` return tokens in service code | 4 in `wifictl/backend.rs`, 1 in `redbear-greeter-compositor` fallback |
|
||
| Hardcoded `val = ...` / `Ok(0)`-style constants in real D-Bus methods | 0 in code; multiple "na" strings |
|
||
| `vec![]` returns in real D-Bus interface methods | 6 (UDisks2 SupportedFilesystems/SupportedEncryptionTypes/Symlinks, etc.; Polkit EnumerateActions; notifications/Idle) |
|
||
| `unimplemented!()` / `todo!()` in any recipe under `local/recipes/system/` | 0 |
|
||
| Daemons referenced in `config/redbear-full.toml` whose binary is not built | 0 (all packages compile) |
|
||
| Daemons in the chain that have **no service file in `redbear-full.toml`** | 2 (`redbear-notifications`, `redbear-statusnotifierwatcher`) |
|
||
| Daemons built but **not started by init** (not in any config) | 2 (`redbear-notifications`, `redbear-statusnotifierwatcher`) |
|
||
| Wireless driver path actually compiled into the chain | 1 (Intel `redbear-iwlwifi`, gated by `/lib/drivers.d/60-wifi.toml`) |
|
||
| **PipeWire / WirePlumber / PulseAudio** in the chain | **0 — not implemented, no recipe, no service** |
|
||
| **`seatd` for Redox backend** in the chain | 0 (upstream seatd only; no `seatd-redox` integration; `redbear-compositor` and KWin use env-var hints instead) |
|
||
| **`pam` / `polkit` with real authority** in the chain | 1 (polkit daemon present, but policy is **a flat file lookup with no JavaScript .rules loading, no auth agent**) |
|
||
| Estimated LoC to finish the minimum to SDDM login screen | ~1,800 LoC (3–4 weeks) |
|
||
| Estimated LoC to finish the minimum to a working Plasma desktop | ~4,500 LoC (8–12 weeks) |
|
||
|
||
### Phase blockers (must clear before `redbear-full` boots to a KDE desktop)
|
||
|
||
1. **D-Bus system bus activation order is a soft failure** — `redbear-sessiond` retries the
|
||
`name` registration 5 times and prints a retry, but if it still fails it exits fatally. The
|
||
order in `redbear-full.toml` is correct (12_dbus → 13_redbear-sessiond → 13_seatd →
|
||
11_redbear-authd → 12_sddm) but `redbear-sessiond` is `oneshot_async`; it is
|
||
*not* a D-Bus `.service` activation. The `org.freedesktop.login1.service` file IS staged
|
||
by `redbear-dbus-services`, but it is essentially unused — `redbear-sessiond` connects to
|
||
the system bus directly as a bus-name owner. This works only because the bus is up.
|
||
2. **No session bus wired into the KDE session.** `redbear-notifications` (which talks to the
|
||
session bus) and `redbear-statusnotifierwatcher` (session bus) are built and installed but
|
||
**no service file starts them in the user session**. KDE Plasma needs the session bus to
|
||
start at user session launch; this is missing.
|
||
3. **seatd is not on the redox backend.** The `seatd` binary is built and its init service
|
||
runs, but the upstream `seatd` is intended for Linux DRM/KMS file descriptor passing.
|
||
Redox has no DRM fd semantics in the Linux sense — `redbear-compositor` and the
|
||
`redbear-greeter-compositor`/`redbear-kde-session` shell scripts use
|
||
`LIBSEAT_BACKEND=seatd` and `SEATD_SOCK=/run/seatd.sock` env vars but no code in the
|
||
Red Bear chain actually calls libseat to open DRM devices. KWin's own seatd code path
|
||
is therefore a no-op; KWin talks directly to `/scheme/drm/card0`.
|
||
4. **No PipeWire / WirePlumber.** The chain stops at `audiod` (the audio device scheme
|
||
daemon). PipeWire and WirePlumber recipes are absent. The kde-session wrapper hardcodes
|
||
`MESA_LOADER_DRIVER_OVERRIDE=virtio_gpu` but does not start any audio session manager.
|
||
5. **No PAM.** `redbear-authd` reads `/etc/passwd` and `/etc/shadow` directly. There is no
|
||
libpam, no `pam_unix.so`, no `pam_systemd.so`. SDDM expects libpam; on Redox it is
|
||
loaded but a real `pam.conf` is absent. Authentication falls through to whatever SDDM's
|
||
PAM stack does, which on Redox is **not** going through `redbear-authd` (see §2.4).
|
||
|
||
### High-level assessment
|
||
|
||
The D-Bus → sessiond → authd → greeter → KWin chain has the **shapes** of a real
|
||
login1/PolicyKit/UPower/UDisks2 stack. Each daemon is real Rust, builds, and the interfaces
|
||
are well-modeled. The fundamental gaps are:
|
||
|
||
* The **user session is not constructed** — there is no session bus, no D-Bus activation in
|
||
the user context, no D-BUS_SESSION_BUS_ADDRESS set by redbear-session-launch.
|
||
* **No PipeWire** for audio.
|
||
* **No PAM** — `redbear-authd` exists but is not the PAM backend SDDM uses.
|
||
* The initfs → rootfs handoff is **two-stage and self-aware**, but the
|
||
D-Bus/system-services directory staging in the *rootfs* (via `redbear-dbus-services` recipe)
|
||
happens via `[[files]]` in `redbear-full.toml` only for the *system* side. The
|
||
`/etc/dbus-1/session.d/` and `/usr/share/dbus-1/session-services/` content from
|
||
`redbear-dbus-services` will be present, but nothing in the user-session launch path
|
||
actually runs `dbus-launch` or sets `DBUS_SESSION_BUS_ADDRESS`.
|
||
* KWin's sessionBus() calls **block on Redox Unix-socket connect()** even when the daemon
|
||
is running (per the explicit comment in `redbear-greeter-compositor` line 81-86).
|
||
This is why KWin's startup `QDBusConnection::sessionBus()` calls have been bypassed in
|
||
the KWin source per the comment. We do not know how many call sites were bypassed
|
||
(the KWin recipe is a built-from-source port); this is a known architectural issue.
|
||
|
||
---
|
||
|
||
## Per-Stage Assessment
|
||
|
||
### 1. D-Bus
|
||
|
||
#### 1.1 Packages
|
||
|
||
| Recipe | Type | Files | Source size | Build state |
|
||
|---|---|---|---|---|
|
||
| `local/recipes/system/dbus` | upstream tarball (dbus 1.16.2) + 24-line `redox.patch` | 102 .c/.h files unpacked (~340k LoC) | 50,000+ LoC | Builds |
|
||
| `local/recipes/system/redbear-dbus-services` | custom (config-only) | 11 .service / .conf files (102 LoC) | 102 LoC | Builds |
|
||
|
||
#### 1.2 `#TODO` in recipe
|
||
|
||
`local/recipes/system/dbus/recipe.toml:1`:
|
||
|
||
```
|
||
#TODO: validate runtime (dbus-daemon --system + dbus-launch for session bus)
|
||
```
|
||
|
||
This is the only `#TODO` in the D-Bus packaging layer. It explicitly calls out that the
|
||
session bus (`dbus-launch` / `dbus-run-session`) has **not been validated** at runtime.
|
||
|
||
#### 1.3 Patch scope
|
||
|
||
`local/recipes/system/dbus/redox.patch` (24 lines) does exactly two things:
|
||
|
||
* `dbus-pollable-set-epoll.c`: relax `#ifndef __linux__` to `#if !defined(__linux__) && !defined(__redox__)`.
|
||
* `dbus-spawn-unix.c`: change `_dbus_socketpair(..., TRUE, ...)` to `... FALSE ...`.
|
||
|
||
The first is a no-op on Redox (the file is for Linux epoll). The second changes the
|
||
socketpair `cloexec` flag from TRUE to FALSE — a behavioral change that may leak file
|
||
descriptors into the babysitter child.
|
||
|
||
#### 1.4 Build configuration
|
||
|
||
`local/recipes/system/dbus/recipe.toml:14-25` disables:
|
||
|
||
* `-Dx11_autolaunch=disabled` (X11 not in scope)
|
||
* `-Dsystemd=disabled` (no systemd)
|
||
* `-Dlaunchd=disabled` (no launchd)
|
||
* `-Dchecks=false` (test code disabled)
|
||
* `-Dasserts=false` (assertions disabled)
|
||
* `-Dxml_docs=disabled`, `-Dducktype_docs=disabled`, `-Ddoxygen_docs=disabled`
|
||
|
||
These are reasonable but mean **D-Bus internal assertions are off in production** — silent
|
||
state-machine corruption will not panic.
|
||
|
||
#### 1.5 Service activation files (in tree)
|
||
|
||
`local/recipes/system/redbear-dbus-services/source/system-services/`:
|
||
|
||
| Service file | Bus name | Exec | Notes |
|
||
|---|---|---|---|
|
||
| `org.freedesktop.login1.service` | `org.freedesktop.login1` | `/usr/bin/redbear-sessiond` | `User=root` |
|
||
| `org.freedesktop.PolicyKit1.service` | `org.freedesktop.PolicyKit1` | `/usr/bin/redbear-polkit` | `User=root`, `SystemdService=redbear-polkit.service` |
|
||
| `org.freedesktop.UPower.service` | `org.freedesktop.UPower` | `/usr/bin/redbear-upower` | `User=root`, `SystemdService=redbear-polkit.service` (note: copy/paste bug — points at polkit not upower) |
|
||
| `org.freedesktop.UDisks2.service` | `org.freedesktop.UDisks2` | `/usr/bin/redbear-udisks` | `User=root`, `SystemdService=redbear-udisks.service` |
|
||
|
||
**Stale code / copy-paste defect:**
|
||
|
||
`local/recipes/system/redbear-dbus-services/source/system-services/org.freedesktop.UPower.service:4`
|
||
sets `SystemdService=redbear-polkit.service`. The `SystemdService=` D-Bus key is
|
||
a hint to activation helpers for systemd-translation, not a hard requirement. It is harmless
|
||
in our context (we use Redox init, not systemd) but it is wrong.
|
||
|
||
`local/recipes/system/redbear-dbus-services/source/session-services/`:
|
||
|
||
| Service file | Bus name | Exec |
|
||
|---|---|---|
|
||
| `org.kde.kded6.service` | `org.kde.kded6` | `env QT_QPA_PLATFORM=offscreen /usr/bin/kded6` |
|
||
| `org.kde.kglobalaccel.service` | `org.kde.kglobalaccel` | `/usr/bin/kglobalacceld` |
|
||
| `org.freedesktop.Notifications.service` | `org.freedesktop.Notifications` | `/usr/bin/redbear-notifications` |
|
||
|
||
The `kded6.service` file forces `QT_QPA_PLATFORM=offscreen` with a comment
|
||
"Qt6 Wayland crashes at null+8 during wl_registry init on Redox" (line 4-5 of that file).
|
||
This is a real workaround for a real Redox/Qt6 bug.
|
||
|
||
There is **no `org.kde.KWin.service` or `org.kde.plasmashell.service`**
|
||
D-Bus activation file in the source tree, even though the
|
||
`redbear-kde-session` wrapper references `kglobalacceld` and KWin.
|
||
|
||
#### 1.6 Policy files
|
||
|
||
`local/recipes/system/redbear-dbus-services/source/system.d/`:
|
||
|
||
* `org.freedesktop.login1.conf` — full access from root + introspection/properties/Manager/Session/Seat from default context. **Reasonable.**
|
||
* `org.freedesktop.PolicyKit1.conf` — root owns; default context may send. **Reasonable.**
|
||
* `org.freedesktop.UDisks2.conf` — root owns; default context may send. **Reasonable but
|
||
too permissive**: a non-root user could mount arbitrary storage. Should be gated through
|
||
polkit (which currently has a one-line `is_authorized`).
|
||
* `org.freedesktop.UPower.conf` — root owns; default context may send. **Same comment.**
|
||
|
||
`local/recipes/system/redbear-dbus-services/source/session.d/`:
|
||
|
||
* `org.redbear.session.conf` — wildcard allow for `org.kde.*`, `org.freedesktop.Notifications`,
|
||
`org.freedesktop.StatusNotifierWatcher`. **Wildcard `.allow own` for `org.kde.*` is a
|
||
permissive default that is acceptable for a single-user desktop but should be documented.**
|
||
|
||
#### 1.7 Service activation order in `redbear-full.toml`
|
||
|
||
* `12_dbus.service` — `cmd = "/usr/bin/dbus-daemon --system --nopidfile"` (line 310).
|
||
* `13_redbear-sessiond.service` — `requires_weak = ["12_dbus.service"]` (line 321).
|
||
* `13_seatd.service` — `requires_weak = ["12_dbus.service", "13_redbear-sessiond.service"]` (line 335).
|
||
* `11_redbear-authd.service` — `requires_weak = ["12_dbus.service"]` (line 439).
|
||
* `12_sddm.service` — requires dbus, sessiond, seatd, authd, evdevd, redox-drm, driver-manager
|
||
(lines 449-460).
|
||
|
||
The order is **correct**. The `type = "oneshot_async"` is the right choice for each of
|
||
the daemons that need to start and stay running.
|
||
|
||
#### 1.8 Missing wirings (D-Bus area)
|
||
|
||
1. **No `redbear-notifications.service` or `redbear-statusnotifierwatcher.service` in any
|
||
config.** Both are built and installed (recipe + package files entry). Neither has
|
||
`[[files]]` in `redbear-full.toml` and neither has a unit file under
|
||
`local/recipes/system/redbear-{notifications,statusnotifierwatcher}/source/init.d/`.
|
||
They will not auto-start.
|
||
2. **No `dbus-launch` invocation in `redbear-session-launch`.** Look at
|
||
`local/recipes/system/redbear-session-launch/source/src/main.rs:341-358`
|
||
(`command_for`) — the function reads `LaunchMode::Session` and returns
|
||
`("/usr/bin/dbus-run-session", vec!["--", "/usr/bin/redbear-kde-session"])`
|
||
if `/usr/bin/dbus-run-session` exists, else just `/usr/bin/redbear-kde-session`. This is
|
||
a thin wrapper, but `dbus-run-session` itself is from dbus, which is built, so the
|
||
wrapper would be used. **However**, in `redbear-kde-session` (line 152) the script does
|
||
`eval "$(dbus-launch --sh-syntax)"` again. So the session bus is started twice — once
|
||
by `dbus-run-session` (which sets `DBUS_SESSION_BUS_ADDRESS`) and once by `dbus-launch`
|
||
(which overwrites it). This is benign in the sense that the second call will use a new
|
||
socket file path, but it leaks a process.
|
||
3. **No `DBUS_SYSTEM_BUS_ADDRESS` set in `redbear-session-launch` for the user
|
||
environment.** It IS set in `redbear-full.toml` via
|
||
`/etc/environment.d/90-dbus.conf:650` to
|
||
`unix:path=/run/dbus/system_bus_socket`. KDE services like `kglobalacceld`,
|
||
`plasma-session`, etc. need both.
|
||
4. **DBUS session bus socket location**: `redbear-session-launch` builds `XDG_RUNTIME_DIR`
|
||
to `/run/user/{uid}` (or `/tmp/run/user/{uid}`), and `dbus-run-session` by default
|
||
creates a socket at `$XDG_RUNTIME_DIR/bus`. SDDM's greeter has UID 102
|
||
(`sddm` user). The user session launched by `redbear-session-launch` will run as
|
||
UID 1000 (`user`). These are two different XDG_RUNTIME_DIRs. `redbear-kde-session`
|
||
sets `XDG_RUNTIME_DIR="/tmp/run/user/$(id -u)"` if unset. The user session bus will
|
||
live at `/tmp/run/user/1000/bus`, the greeter session bus will live at
|
||
`/var/lib/sddm` (or wherever the greeter's XDG_RUNTIME_DIR is). KDE Plasma connects
|
||
to the bus at `XDG_RUNTIME_DIR/bus`, so this is consistent for the user session
|
||
**but the SDDM greeter is not wired**.
|
||
5. **No `org.kde.KWin.service`, `org.kde.plasmashell.service`,
|
||
`org.kde.kglobalacceld.service`** in the source tree. Without these, kglobalacceld
|
||
and plasma-shell will not auto-activate via D-Bus on a fresh session.
|
||
6. **No system-bus `.service` for `redbear-authd`.** The authd doesn't speak D-Bus (it
|
||
speaks a JSON-over-Unix-socket protocol). The `redbear-greeter` connects to
|
||
`/run/redbear-authd.sock` directly (see `local/recipes/system/redbear-greeter/source/src/main.rs:135-150`).
|
||
This is fine for the greeter flow but SDDM itself does not connect to authd — it
|
||
expects to go through PAM.
|
||
|
||
#### 1.9 Stale / half-impl code (D-Bus area)
|
||
|
||
* `redbear-sessiond/source/src/manager.rs:171-188` — `power_off`, `reboot`, `suspend` all
|
||
log a message and return `Ok(())`. They do not call any actual shutdown or reboot
|
||
system call. The `redbear-greeter` calls `AuthRequest::PowerAction` → authd
|
||
`run_power_action` which actually invokes `/usr/bin/shutdown` or `/usr/bin/poweroff`
|
||
(see `redbear-authd/source/src/main.rs:342-361`). So the **end-to-end power flow works
|
||
through authd, not sessiond**. sessiond's power methods are correct DBus no-ops because
|
||
the request gets re-dispatched via authd. **Stale-but-correct.**
|
||
* `redbear-sessiond/source/src/session.rs:206-212` — `kill` logs a message and returns
|
||
`Ok(())`. SDDM may call this to terminate the user's session. It is a stub. A real impl
|
||
would send SIGTERM to `runtime.leader`.
|
||
* `redbear-sessiond/source/src/manager.rs:329-330, 339-341` — `KillSession` and `KillUser`
|
||
log "no-op" and return `Ok(())`. Same as above.
|
||
* `redbear-polkit/source/src/main.rs:144` — `CheckAuthorization` always
|
||
returns `(is_authorized(0, action_id), !authorized, ...)` — i.e. always queries the
|
||
policy file with `uid=0`. **This means polkit always reports the result for root, even
|
||
when the caller is not root.** The function signature takes no UID argument; it has
|
||
no way to know the caller. **This is a security defect**, but in practice only `root`
|
||
and `sddm` (uid 102) can call D-Bus methods to polkit on Redox given the policy files.
|
||
The fix is to use the D-Bus `caller` mechanism (zbus provides this via the connection
|
||
metadata) or to read the peer's UID from the socket.
|
||
|
||
#### 1.10 D-Bus area: missing wirings summary
|
||
|
||
| # | Missing | Impact |
|
||
|---|---|---|
|
||
| 1 | `redbear-notifications` service file | KDE notifications will not appear |
|
||
| 2 | `redbear-statusnotifierwatcher` service file | System tray will be empty |
|
||
| 3 | `org.kde.KWin.service` D-Bus activation | KWin will not auto-activate |
|
||
| 4 | `org.kde.kglobalacceld.service` D-Bus activation | Global shortcuts won't work |
|
||
| 5 | `org.kde.plasmashell.service` D-Bus activation | Plasma shell may not auto-start |
|
||
| 6 | `redbear-sessiond` `kill`/`power_*` real impls | Power off / reboot will be via authd but signal handling is brittle |
|
||
| 7 | polkit caller-UID extraction | Privilege boundary is broken |
|
||
|
||
|
||
---
|
||
|
||
### 2. Session Management
|
||
|
||
#### 2.1 `redbear-sessiond` (`org.freedesktop.login1`)
|
||
|
||
**Location:** `local/recipes/system/redbear-sessiond/source/src/`
|
||
**LoC:** 2,017 (across `main.rs`, `manager.rs`, `session.rs`, `seat.rs`, `control.rs`,
|
||
`device_map.rs`, `runtime_state.rs`, `acpi_watcher.rs`)
|
||
**Bus name:** `org.freedesktop.login1`
|
||
**Implementation language:** Rust, `zbus = "5"` with `tokio` runtime.
|
||
|
||
The implementation is the **most complete** piece of the chain. The `LoginManager`,
|
||
`LoginSession`, `LoginSeat` interfaces all map cleanly to the freedesktop.org
|
||
specification, and the runtime state is shared via `Arc<RwLock<SessionRuntime>>`
|
||
(`runtime_state.rs:50`).
|
||
|
||
**Tests:** Each module has unit tests in a `#[cfg(test)] mod tests` block. Total: ~30
|
||
test functions. All use `shared_runtime()` for isolated state.
|
||
|
||
##### 2.1.1 Real implementations
|
||
|
||
* `get_session`, `list_sessions`, `get_seat`, `get_user`, `list_users`, `list_seats`
|
||
(`manager.rs:65-209`) — all return paths derived from runtime state.
|
||
* `inhibit` (`manager.rs:103-141`) — returns a real `OwnedFd` from a Unix stream pair,
|
||
tracks the entry in runtime.
|
||
* `activate_session`, `activate_session_on_seat`, `lock_session`, `unlock_session`,
|
||
`lock_sessions`, `unlock_sessions`, `terminate_session`, `terminate_user`
|
||
(`manager.rs:229-320`) — all update runtime state and return `Ok`.
|
||
* `LoginSession::take_control`, `release_control`, `take_device`, `release_device`
|
||
(`session.rs:78-150`) — real implementation with a `controlled` mutex and
|
||
`taken_devices: HashSet<(u32, u32)>`. `take_device` opens a real file from
|
||
`DeviceMap::open_device` (which returns a real `File`).
|
||
* `set_idle_hint`, `set_locked_hint`, `set_type`, `terminate` (`session.rs:160-204`) —
|
||
all update runtime state.
|
||
* `LoginSeat::switch_to` (`seat.rs:65-80`) — invokes `inputd -A <vt>` via
|
||
`Command::new("inputd").args(["-A", &vt.to_string()])`. This is the real VT switch.
|
||
|
||
##### 2.1.2 Stubs (returns 0 / no-op / "na")
|
||
|
||
* `can_power_off`, `can_reboot`, `can_suspend`, `can_hibernate`, `can_hybrid_sleep`,
|
||
`can_suspend_then_hibernate`, `can_sleep` (`manager.rs:143-169`) — all return
|
||
`Ok(String::from("na"))`. Per the freedesktop.org spec, "na" means "not available".
|
||
The KDE Power Management plasmoid and SDDM both check `CanPowerOff`/`CanReboot` and
|
||
will **hide the corresponding buttons** if "na" is returned. This means the user
|
||
cannot trigger a clean shutdown from the SDDM greeter without the manual
|
||
`RequestShutdown` path. The fix is to check whether the `shutdown` binary exists.
|
||
* `IdleSinceHint`, `IdleSinceHintMonotonic` (`manager.rs:349-357`) — both return `0`.
|
||
These are timestamp values that should reflect when the session became idle. A
|
||
constant `0` means "idle since epoch" which is wrong.
|
||
* `InhibitDelayMaxUSec` (`manager.rs:387-390`) — returns `0`. Per the spec, this is
|
||
the max delay (in microseconds) an inhibitor can request. `0` is "no delay", which
|
||
is conservative but correct.
|
||
* `HandleLidSwitch` (`manager.rs:393-395`) — returns `"ignore"`. The kernel has a
|
||
real ACPI lid switch. We should wire this to "suspend" or "poweroff".
|
||
* `HandlePowerKey` (`manager.rs:398-400`) — returns `"poweroff"`. Reasonable default.
|
||
* `PreparingForSleep` (`manager.rs:402-404`) — always `false`. Real impl would track
|
||
the suspend state machine.
|
||
* `power_off`, `reboot`, `suspend` (`manager.rs:171-187`) — log and return `Ok(())`.
|
||
No actual call to `reboot()` syscall or ACPI shutdown register. Power action
|
||
flows through `redbear-authd` instead (see `redbear-authd/source/src/main.rs:342-361`).
|
||
* `get_session_by_pid`, `get_user_by_pid` (`manager.rs:189-195`) — always return
|
||
the current session/user. A real impl would scan `/proc`.
|
||
* `LoginSession::kill` (`session.rs:206-212`) — log "no-op" and return `Ok(())`. A
|
||
real impl would `kill(runtime.leader, signal_number)`.
|
||
* `LoginManager::kill_session`, `kill_user` (`manager.rs:322-342`) — same as above.
|
||
* `PauseDeviceComplete` (`session.rs:152-158`) — log only. Real impl would
|
||
resume I/O on the device.
|
||
|
||
##### 2.1.3 DeviceMap
|
||
|
||
`device_map.rs` provides a real implementation that discovers `/scheme/drm/card*` and
|
||
`/dev/input/event*` at startup and merges them with static fallback entries
|
||
(`(226, 0) -> "/scheme/drm/card0"` etc.). It uses `rdev()` from `MetadataExt` to map
|
||
inode-style device numbers to (major, minor).
|
||
|
||
**Stale code in `device_map.rs`:**
|
||
|
||
* `dev_major` (`device_map.rs:230-232`) — the implementation
|
||
```
|
||
fn dev_major(device: u64) -> u32 {
|
||
(((device >> 31 >> 1) & 0xfffff000) | ((device >> 8) & 0x00000fff)) as u32
|
||
}
|
||
```
|
||
is an unusual bit-pick from a packed Linux `dev_t`. This is the Linux-style 32-bit
|
||
dev_t encoding, but Redox's `Metadata::rdev()` returns a Redox-native device
|
||
identifier, **not** the Linux encoding. The unit tests in `device_map.rs:241-258`
|
||
use `make_dev` which constructs a *Linux-shaped* dev_t, so the tests pass but the
|
||
real `rdev()` value from a Redox file may not match. **This is a stale-code bug.**
|
||
* The fallback logic (`device_map.rs:87-99`) is real and uses `Path::exists()` — but
|
||
`Path::exists()` on Redox scheme paths is unreliable (the
|
||
`redbear-greeter-compositor` script uses `( exec 3<"/scheme/drm/card0" )` instead
|
||
of `test -e` or `stat`). The `DeviceMap` should be using the same pattern.
|
||
|
||
##### 2.1.4 ACPI watcher
|
||
|
||
`acpi_watcher.rs` is 48 lines and exposes `watch_and_emit(connection, runtime)` which
|
||
spawns a tokio task. **Stale code**: only the function signature is in the source;
|
||
the actual implementation is in a separate patch
|
||
`local/patches/redbear-sessiond/P4-signal-implementations.patch` (referenced from
|
||
`local/recipes/system/redbear-sessiond/recipe.toml:3`).
|
||
|
||
#### 2.2 `redbear-authd`
|
||
|
||
**Location:** `local/recipes/system/redbear-authd/source/src/main.rs`
|
||
**LoC:** 719
|
||
**Implementation language:** Rust, with `argon2`, `sha-crypt`, `redbear-login-protocol`.
|
||
|
||
This is the **most-tested** piece of the chain — 12 unit tests covering password
|
||
verification, lockout, VT mismatch, etc.
|
||
|
||
##### 2.2.1 Real implementations
|
||
|
||
* `load_shadow_passwords` (lines 102-123) — reads `/etc/shadow` line-by-line.
|
||
* `load_account` (lines 125-171) — reads `/etc/passwd` and joins with shadow.
|
||
* `verify_shadow_password` (lines 184-194) — handles `$6$` (SHA-512 crypt), `$5$`
|
||
(SHA-256 crypt), `$argon2`. **Real, robust.**
|
||
* `verify_password` (lines 196-215) — handles plain text, locked (`!`/`*`), and
|
||
hashed passwords.
|
||
* `login_allowed` (lines 177-182) — refuses non-root with uid < 1000, refuses empty
|
||
shell.
|
||
* `remember_success`, `remember_failure`, `check_lockout` (lines 217-271) — real
|
||
rate-limiting with a 60-second window and 30-second lockout.
|
||
* `take_approval` (lines 273-288) — 15-second expiry on auth approval, VT mismatch
|
||
rejection.
|
||
* `run_power_action` (lines 342-361) — invokes `/usr/bin/shutdown`, `shutdown`, or
|
||
`poweroff` in that order.
|
||
* `handle_request` (lines 363-451) — dispatch for Authenticate / StartSession /
|
||
PowerAction.
|
||
|
||
##### 2.2.2 Stubs / half-impls
|
||
|
||
* `send_sessiond_update` (lines 290-299) — silently fails on
|
||
`UnixStream::connect(SESSIOND_SOCKET_PATH)` failure. If `redbear-sessiond` is not
|
||
running (or hasn't created the control socket), the auth result will not propagate
|
||
to the runtime. **Connection failures should be logged.**
|
||
* `launch_session` (lines 301-340) — hard-codes `kde-wayland` as the only supported
|
||
session. Any other session name returns `Err("unsupported session '...'")`. This
|
||
is fine for a single-session kiosk but blocks any X11 fallback.
|
||
* `VALIDATION_REQUEST_PATH` (line 25) is a hardcoded path
|
||
`/run/redbear-kde-session.validation-request`. The validation-request mechanism
|
||
is a Red Bear test harness for "did the compositor expose a Wayland socket". It
|
||
is **not** a real authd concept. The `Path::new(VALIDATION_REQUEST_PATH).exists()`
|
||
check on line 326 changes the wait behavior from blocking (`child.wait()`) to
|
||
fire-and-forget. This is a test-harness leak into the production code path.
|
||
|
||
##### 2.2.3 `login_allowed` strictness
|
||
|
||
`login_allowed` (line 177-182) rejects any non-root account with `uid < 1000`. The
|
||
config-defined `messagebus` user is uid 100, `greeter` is uid 101, `sddm` is uid 102.
|
||
None of them can log in. This is by design (service accounts, not users) but it
|
||
means a config that puts a real user at uid 999 will be silently rejected.
|
||
|
||
#### 2.3 `redbear-session-launch`
|
||
|
||
**Location:** `local/recipes/system/redbear-session-launch/source/src/main.rs`
|
||
**LoC:** 628
|
||
**Implementation language:** Rust, no async, uses `std::os::unix::process::CommandExt`.
|
||
|
||
##### 2.3.1 Real implementations
|
||
|
||
* `parse_passwd` (lines 133-170) — handles both Redox `;` and Unix `:` layouts.
|
||
* `parse_groups` (lines 172-199).
|
||
* `load_supplementary_groups` (lines 210-226).
|
||
* `build_environment` (lines 252-323) — sets all the KDE-required env vars:
|
||
`XDG_CURRENT_DESKTOP=KDE`, `KDE_FULL_SESSION=true`, `XDG_SESSION_ID=c1`,
|
||
`WAYLAND_DISPLAY=wayland-0`, `XDG_SEAT=seat0`, `XDG_VTNR=<vt>`,
|
||
`XDG_SESSION_TYPE=wayland`, `XDG_RUNTIME_DIR=<runtime_dir>`. Also forces
|
||
`KWIN_DRM_DEVICES=/scheme/drm/card0` if the env var is unset (line 290-293).
|
||
* `apply_groups` (lines 325-339) — `cfg(target_os = "redox")` returns `Ok(())`
|
||
(no-op); non-redox calls `libc::setgroups`. This is **correct for Redox** because
|
||
the kernel does not yet have a real supplementary-groups syscall. Per the project
|
||
README, supplementary groups were added 2026-04-30 — but `apply_groups` was not
|
||
updated to actually use them. **Stale code.**
|
||
* `command_for` (lines 341-358) — returns `/usr/bin/dbus-run-session -- /usr/bin/redbear-kde-session`
|
||
for the `kde-wayland` session, else error.
|
||
* `run` (lines 361-394) — `env_clear()`s, sets env, calls `command.uid(...)` and
|
||
`command.gid(...)` and `command.pre_exec(apply_groups)`, then `command.exec()`.
|
||
|
||
##### 2.3.2 Stubs / half-impls
|
||
|
||
* `apply_groups` no-op on Redox (see 2.3.1).
|
||
* No `setrlimit` calls. Some KDE processes (e.g. `kwin_wayland`) want increased
|
||
resource limits.
|
||
* No PR_SET_PDEATHSIG — if `redbear-session-launch` crashes after `exec`, the
|
||
child process becomes orphaned. SDDM expects the launched session to die with
|
||
its launcher.
|
||
|
||
#### 2.4 `redbear-greeter`
|
||
|
||
**Location:** `local/recipes/system/redbear-greeter/source/src/main.rs`
|
||
**LoC:** 656
|
||
**Two side scripts:** `redbear-greeter-compositor` (Bash, 4,310 bytes),
|
||
`redbear-kde-session` (Bash, 8,936 bytes)
|
||
|
||
##### 2.4.1 Real implementations
|
||
|
||
* `GreeterDaemon::new` (lines 163-196) — binds `/run/redbear-greeterd.sock`, sets
|
||
0o660, chowns to the `greeter` user.
|
||
* `load_uid_gid` (lines 106-122) — reads `/etc/passwd`, handles both layouts.
|
||
* `change_socket_ownership` (lines 124-133) — `libc::chown`.
|
||
* `start_surface` (lines 261-279) — spawns `redbear-greeter-compositor` (which in
|
||
turn launches `kwin_wayland --drm /scheme/drm/card0` or `redbear-compositor`),
|
||
waits for the Wayland socket (up to 30 seconds), then launches the QML greeter
|
||
UI as the `greeter` user.
|
||
* `note_restart` (lines 289-299) — bounds restart attempts to 3 per minute.
|
||
* `handle_connection` (lines 346-439) — processes Hello, SubmitLogin,
|
||
RequestShutdown, RequestReboot.
|
||
* `launch_session` (lines 319-344) — sends `AuthRequest::StartSession` to
|
||
`redbear-authd`, which then forks `redbear-session-launch` to start KDE.
|
||
* 10 unit tests.
|
||
|
||
##### 2.4.2 Stubs / half-impls
|
||
|
||
* `COMPOSITOR_BIN_PATH` (line 18) is `/usr/bin/redbear-greeter-compositor` and
|
||
`COMPOSITOR_SHARE_PATH` (line 19) is `/usr/share/redbear/greeter/redbear-greeter-compositor`.
|
||
The daemon picks whichever exists (`Path::is_file()` at line 264). **The recipe
|
||
installs both.** This is not a stub but is redundant.
|
||
* `wait_for_wayland_socket` (lines 250-259) — polls every 250ms for 30 seconds. The
|
||
daemon will report `FatalError` (line 295) after 3 restarts in 60 seconds. There
|
||
is no override for users to bypass the failure; they cannot log in.
|
||
* `handle_connection` does not validate the `version` of the request beyond
|
||
`version != 1` (line 361). Future protocol versions are not negotiated.
|
||
* `redbear-greeter-compositor` (Bash script) — line 81-86 has an explicit comment
|
||
acknowledging that **Qt6's QDBusConnection::sessionBus() blocks on Redox
|
||
Unix-socket connect()** even when the daemon is running, and that KWin's
|
||
sessionBus() calls in the startup path have been bypassed. This is a known
|
||
architectural issue. It also forces `MESA_LOADER_DRIVER_OVERRIDE=virtio_gpu`
|
||
unconditionally, which is wrong for Intel/AMD targets.
|
||
* `redbear-greeter-compositor:60-66` — the `wait_for_drm_scheme` polls for 10
|
||
seconds (configurable via `REDBEAR_DRM_WAIT_SECONDS`) using the open-as-probe
|
||
pattern. This is correct, not a stub.
|
||
* `redbear-greeter-compositor:75-86` — fallback path: if no DRM device, runs
|
||
`$COMPOSITOR` again without `KWIN_DRM_DEVICES`. The comment says "no DRM at all —
|
||
fall back to virtual backend." The `$COMPOSITOR` here is `kwin_wayland` or
|
||
`redbear-compositor`, neither of which is the *virtual* QPA backend — they are
|
||
both Wayland compositors. **A real virtual fallback would set
|
||
`QT_QPA_PLATFORM=offscreen` or `minimal`**, not just unset the device. This is
|
||
a half-impl: the env var unset is correct for KWin's `--virtual` mode but
|
||
`--virtual` is not passed.
|
||
|
||
##### 2.4.3 `redbear-kde-session` (Bash) — half-impls
|
||
|
||
This script is what runs after a successful auth. Real impls:
|
||
|
||
* Sets KDE env vars (lines 36-54).
|
||
* Writes `/run/redbear-kde-session.env` (the session env file consumed by
|
||
`dbus-update-activation-environment`).
|
||
* Calls `dbus-update-activation-environment` if available.
|
||
* Falls back to virtual if `KWIN_DRM_DEVICES` is empty AND DRM is not ready
|
||
(lines 117-145).
|
||
* Waits for the Wayland socket (up to 40 seconds) (lines 184-202).
|
||
|
||
Stubs and leaks:
|
||
|
||
* Line 152: `if [ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ] && command -v dbus-launch >/dev/null 2>&1; then eval "$(dbus-launch --sh-syntax)"; fi`
|
||
— this starts **a second session bus** on top of the one started by
|
||
`dbus-run-session` in `redbear-session-launch`. The first bus address is
|
||
discarded. The two buses are independent processes, which can confuse KDE
|
||
components that use `qdbus` to talk to the bus.
|
||
* Line 207: `kded6` is launched with `QT_QPA_PLATFORM=offscreen` to work around
|
||
the Qt6 Wayland null+8 crash. This is fine but means KDE services that depend
|
||
on kded6 graphics will not function correctly.
|
||
* Line 208: `plasmashell` is launched with no QPA override. **It will crash
|
||
on the Qt6 Wayland null+8 bug** unless the upstream KWin build avoids the
|
||
crash. This is a probable runtime failure on `redbear-full`.
|
||
* Line 209: `wait "$kwin_pid"` — the script will not exit until kwin dies. If
|
||
kwin dies with a non-zero exit, the script returns that exit code. There is
|
||
no logic to relaunch kwin or to enter a degraded mode.
|
||
|
||
#### 2.5 Service activation order (Session Management)
|
||
|
||
The chain on `redbear-full`:
|
||
|
||
```
|
||
12_dbus.service
|
||
└─ dbus-daemon --system
|
||
13_redbear-sessiond.service
|
||
└─ redbear-sessiond (zbus, claims org.freedesktop.login1)
|
||
13_seatd.service
|
||
└─ seatd -l info
|
||
11_redbear-authd.service
|
||
└─ redbear-authd (Unix socket, not D-Bus)
|
||
[12_sddm.service]
|
||
└─ sddm (expects PAM; expects login1; expects seatd)
|
||
```
|
||
|
||
The chain on `redbear-mini` is the same but with seatd replaced by an
|
||
`echo "seatd: skipped on live-mini"` (line 393 of `redbear-mini.toml`).
|
||
|
||
**Missing wire:** the `redbear-full.toml` does **not** define a
|
||
`12_greeter.service` that launches `redbear-greeterd`. It defines `12_sddm.service`
|
||
directly. SDDM in turn is expected to be the greeter. This is consistent with the
|
||
overall design ("SDDM is the login screen"), but the redbear-greeter implementation
|
||
exists alongside — it is unused on `redbear-full`. This is **dead code** unless we
|
||
decide to swap SDDM for the redbear-greeter.
|
||
|
||
#### 2.6 Cross-cutting session issues
|
||
|
||
1. **SDDM does not talk to `redbear-authd`.** SDDM expects PAM. The
|
||
`local/sources/relibc` (Redox relibc) does not ship a `libpam`. SDDM's PAM
|
||
stack will fail to load. SDDM is built (`recipes/wip/...`) and packaged
|
||
(`redbear-full.toml:156 sddm = {}`), but **the runtime path is broken**
|
||
unless a fake `pam_unix.so` is shipped that proxies to `redbear-authd`.
|
||
2. **SDDM's expected GreeterEnvironment includes `WAYLAND_DISPLAY`**, but the
|
||
`redbear-full.toml:572` `sddm.conf` only sets `QT_PLUGIN_PATH`,
|
||
`QML2_IMPORT_PATH`, `QT_QPA_PLATFORM_PLUGIN_PATH`. **Missing
|
||
`WAYLAND_DISPLAY=wayland-0`** and `XDG_SESSION_TYPE=wayland`.
|
||
3. **`redbear-kde-session` is not started by SDDM** — the
|
||
`/usr/share/wayland-sessions/plasmawayland.desktop` (lines 593-601 of
|
||
`redbear-full.toml`) `Exec` is `/usr/bin/kwin_wayland --drm /scheme/drm/card0`.
|
||
That launches **just kwin**, not plasmashell, kded6, kglobalacceld, etc. The
|
||
user will see a black screen with a cursor.
|
||
|
||
---
|
||
|
||
### 3. Seat Management (seatd)
|
||
|
||
#### 3.1 Location
|
||
|
||
* Recipe: `local/recipes/system/seatd/recipe.toml` (16 lines, upstream
|
||
`https://git.sr.ht/~kennylevinsen/seatd/archive/0.9.1.tar.gz`).
|
||
* Source: `local/recipes/system/seatd/source/`
|
||
* Total LoC: 2,003 in `seatd/*.c`.
|
||
|
||
#### 3.2 Is it built? — Yes
|
||
|
||
`redbear-mini.toml:387-396` defines a seatd service but it is a no-op
|
||
(`cmd = "echo"; args = ["seatd: skipped on live-mini"]`). `redbear-full.toml:330-342`
|
||
defines the real `seatd -l info`.
|
||
|
||
#### 3.3 Is it started before SDDM? — Yes, but not used
|
||
|
||
The order in `redbear-full.toml:330` is:
|
||
|
||
```
|
||
13_seatd.service
|
||
requires_weak = [
|
||
"12_dbus.service",
|
||
"13_redbear-sessiond.service",
|
||
]
|
||
```
|
||
|
||
`12_sddm.service:454-460` requires `13_seatd.service`. So the order is correct.
|
||
|
||
#### 3.4 Does it work? — Partially
|
||
|
||
`seatd` is a C daemon that accepts connections on `/run/seatd.sock` and brokers
|
||
DRM master, input device, and tty access. The `redbear-full.toml:444` env block
|
||
sets `SEATD_SOCK=/run/seatd.sock` for authd, and `redbear-session-launch:272`
|
||
sets `SEATD_SOCK=/run/seatd.sock` and `LIBSEAT_BACKEND=seatd` for the user session.
|
||
|
||
**However:**
|
||
|
||
* `redbear-compositor` (`local/recipes/wayland/redbear-compositor/source/`) and
|
||
KWin (built from upstream) expect to call `libseat_open_device()` to obtain a
|
||
DRM file descriptor. The Redox DRM scheme is not file-descriptor-based in the
|
||
Linux sense — `/scheme/drm/card0` is a control channel, not a stream. So
|
||
`libseat_open_device()` will succeed at the libseat level but the returned fd
|
||
is meaningless.
|
||
* The actual `KWin::OpenDrmDevice()` path on Redox uses
|
||
`KWIN_DRM_DEVICES=/scheme/drm/card0` env var and opens the scheme path
|
||
directly via `QFile`. This bypasses seatd entirely.
|
||
* `seatd` is therefore running but **not actually being used** for DRM access.
|
||
The same is true for input devices: `evdevd` exposes them as scheme paths,
|
||
not Linux fds.
|
||
|
||
#### 3.5 Stubs / stale code (seatd)
|
||
|
||
* `seatd` is upstream 0.9.1. It has a `#if defined(__linux__)` path for evdev and
|
||
DRM. On Redox, those code paths are not compiled. The `meson.build` is
|
||
unmodified; it will use whatever backend is auto-detected. The
|
||
`common/drm.c` and `common/evdev.c` are Linux-only.
|
||
|
||
#### 3.6 Cross-cutting seat issues
|
||
|
||
* **SDDM-KWin-libseat integration** is non-functional. The fallback in
|
||
`redbear-greeter-compositor:60-66` (open-as-probe) is what KWin actually relies on.
|
||
* **No fallback for SDDM** if `seatd` rejects seat creation. SDDM aborts.
|
||
* **`CanGraphical` is hardcoded `true` in `LoginSeat`** (`seat.rs:97-99`).
|
||
This is fine if seatd succeeds, but if seatd is unable to attach the seat to
|
||
a graphics device, the property should be `false`. The check is done in
|
||
`seatd`, not in redbear-sessiond.
|
||
|
||
|
||
---
|
||
|
||
### 4. Audio / PipeWire
|
||
|
||
#### 4.1 `audiod` daemon
|
||
|
||
**Location:** `local/sources/base/audiod/src/`
|
||
**LoC:** 277 (100 main.rs + 177 scheme.rs)
|
||
**Built into the rootfs**: yes, via `local/sources/base/init.d/20_audiod.service`
|
||
(declared in `local/sources/base/init.d/20_audiod.service`).
|
||
|
||
The `redbear-mini.toml:178-190` overrides the init.d entry with a `oneshot_async`
|
||
copy. The `redbear-full.toml` does not override it, so it inherits the rootfs default.
|
||
|
||
##### 4.1.1 Real implementations
|
||
|
||
* `audiod` opens `/scheme/audiohw` (line 51) and, on success, enters a constrained
|
||
namespace and a scheme request loop. If `/scheme/audiohw` does not exist, the
|
||
daemon **exits with code 0** (line 55: `eprintln!("audiod: no audio hardware
|
||
found, exiting ({e})"); process::exit(0);`). This is the correct behavior
|
||
for systems without audio hardware.
|
||
* The scheme backend (`scheme.rs`) implements the audio scheme — the same scheme
|
||
is used by QEMU's `ac97` and Intel HDA drivers.
|
||
|
||
##### 4.1.2 Stubs / half-impls
|
||
|
||
* None in the daemon itself. The daemon is small, well-bounded, and works.
|
||
|
||
#### 4.2 PipeWire / WirePlumber
|
||
|
||
**PipeWire recipe:** none. **WirePlumber recipe:** none. **PulseAudio recipe:** none.
|
||
|
||
The chain stops at `audiod`. There is no session audio manager.
|
||
|
||
For KDE Plasma to make sound:
|
||
|
||
* PipeWire (or PulseAudio) must be running.
|
||
* WirePlumber (if PipeWire) must be running to manage the policy.
|
||
* The `XDG_SESSION_ID` and `PIPEWIRE_REMOTE` env vars must be set in the user
|
||
session.
|
||
* `pw-cli` and the KDE audio integration (`libKF6PulseAudioOtp`, or
|
||
`plasma-pa`) must link against libpipewire.
|
||
|
||
**None of this exists in the current chain.** KDE Plasma will compile and
|
||
link with `plasma-pa` (which is part of the upstream Redox build), but at
|
||
runtime the audio backend is not present, and any KDE app that tries to play
|
||
audio will fail.
|
||
|
||
#### 4.3 PipeWire integration with redbear-kde-session
|
||
|
||
The `redbear-kde-session` script does not start `pipewire` or `wireplumber`.
|
||
The session is missing the audio subsystem entirely.
|
||
|
||
#### 4.4 Cross-cutting audio issues
|
||
|
||
1. **No PipeWire port**. The Redox Audio scheme (`scheme:audio`) is not the
|
||
same as `pulseaudio` or `pipewire`. KDE's audio applet looks for
|
||
`org.pulseaudio.Server` on the session bus; it is not present.
|
||
2. **No WirePlumber**. Even if PipeWire existed, the policy daemon is missing.
|
||
3. **No per-user audio routing**. `audiod` is a system daemon. There is no
|
||
per-session audio.
|
||
4. **No USB audio integration**. `redbear-usbaudiod` is in `redbear-mini.toml:59`
|
||
but is the daemon for USB audio devices, not the audio session manager. It
|
||
exposes `/scheme/audiohw` for the USB audio class.
|
||
|
||
---
|
||
|
||
### 5. Network
|
||
|
||
#### 5.1 Network stack (kernel + netstack)
|
||
|
||
* Kernel: `local/sources/kernel/` (Red Bear fork). TCP/IP is in the kernel.
|
||
* Userspace: `local/sources/base/netstack/` (428 LoC across 5 files).
|
||
* Network driver spawner: `pcid-spawner` (rootfs) → drivers like `e1000d`,
|
||
`virtio-netd`, etc.
|
||
|
||
The netstack is small (198 LoC main.rs) but is the userspace component that
|
||
listens to `/scheme/network*` and bridges to smoltcp. It is a **scheme daemon,
|
||
not a regular service**.
|
||
|
||
#### 5.2 DHCP
|
||
|
||
* `dhcpd` lives in `local/sources/base/dhcpd/src/main.rs` (497 LoC).
|
||
* The rootfs init.d entry is `10_dhcpd.service` (line 5 of `init.d/10_dhcpd.service`):
|
||
`cmd = "dhcpd"`, type `oneshot_async`.
|
||
* `redbear-mini.toml:133-146` overrides to `cmd = "dhcpd"`, args `["-f"]`, type
|
||
`oneshot_async`. `redbear-full.toml` inherits.
|
||
* `redbear-netctl` (see 5.5) calls `dhcpd` to start a DHCP client.
|
||
|
||
**Status:** the daemon is built and runs on boot (rootfs). It exits when the
|
||
DHCP lease is acquired (or times out).
|
||
|
||
#### 5.3 DNS
|
||
|
||
There is no userspace DNS daemon in the chain. `relibc` (Redox C library) has a
|
||
`/etc/resolv.conf` parser and the `netstack` (smoltcp) supports DNS. The
|
||
`redbear-netctl:277` `write_netcfg("resolv/nameserver", dns)` writes a nameserver
|
||
line to the netstack's scheme.
|
||
|
||
**Stale code:** `resolv/nameserver` is a single value, not multi-valued.
|
||
glibc/POSIX allows multiple `nameserver` lines. Redox stores only one. This is
|
||
a known Redox limitation, not a Red Bear issue.
|
||
|
||
#### 5.4 Wi-Fi (wifictl + iwlwifi)
|
||
|
||
##### 5.4.1 `redbear-wifictl` (control plane)
|
||
|
||
**Location:** `local/recipes/system/redbear-wifictl/source/src/`
|
||
**LoC:** 2,786 (backend.rs 1509, main.rs 487, scheme.rs 743, dbus_nm.rs 47)
|
||
|
||
* Three backends: `StubBackend`, `NoDeviceBackend`, `IntelBackend`
|
||
(backend.rs:134-322).
|
||
* `build_backend` (main.rs:98-118) selects based on
|
||
`REDBEAR_WIFICTL_BACKEND`, presence of `/usr/lib/drivers/redbear-iwlwifi`,
|
||
and detected Intel interfaces.
|
||
* `select_backend_mode` (main.rs:81-96) returns `BackendMode::Stub` if no
|
||
driver is present, even on Redox runtime. **Stub is the default on
|
||
non-Intel hardware.**
|
||
|
||
##### 5.4.2 `StubBackend` — this is a stub
|
||
|
||
`backend.rs:140-245` — the `StubBackend` is a stub that returns canned
|
||
strings for every method:
|
||
|
||
* `scan()` returns `["demo-ssid", "demo-open"]` (line 186-188).
|
||
* `connect()` returns `WifiStatus::Connected` for open or wpa2-psk-with-key.
|
||
* `firmware_status()` returns `"firmware=stub"`.
|
||
* `transport_status()` returns `"transport=stub"`.
|
||
* `init_transport()` returns `"transport_init=stub"`.
|
||
|
||
This is **explicitly a stub** — a placeholder for hardware that has not yet
|
||
been wired. The README says "bounded Intel Wi-Fi driver path" is the only
|
||
real path. On non-Intel hardware, wifictl reports fake SSIDs.
|
||
|
||
**Per project policy**, stubs must be replaced. The fix is to either:
|
||
1. Remove `StubBackend` entirely and require the Intel driver to be present.
|
||
2. Port more drivers (e.g., `ath9k`, `mt76`).
|
||
3. Document `StubBackend` as a test-harness back-end and gate it on
|
||
`cfg(test)` or a CLI flag.
|
||
|
||
##### 5.4.3 `NoDeviceBackend` — also a stub but reasonable
|
||
|
||
`backend.rs:247-320` — returns `Err("no Intel Wi-Fi device detected")` for
|
||
every action. This is correct: it is the backend used when the driver is
|
||
present but no device is found.
|
||
|
||
##### 5.4.4 `IntelBackend` — real implementation
|
||
|
||
`backend.rs:322+` — this is the real implementation. It uses
|
||
`redox_driver_sys::pci::parse_device_info_from_config_space` and runs the
|
||
`/usr/lib/drivers/redbear-iwlwifi` binary for `--prepare`, `--init-transport`,
|
||
`--activate-nic`, `--scan`, `--connect`, `--disconnect`, `--retry`. Falls back
|
||
to `program_transport_bits` and `activate_nic_action` helpers if the driver
|
||
binary errors out.
|
||
|
||
**Stale code:**
|
||
|
||
* `scan` (line 519-528) — if the driver's `--scan` returns no results, the
|
||
result list is set to `["driver-scan-not-implemented"]`. This is a placeholder
|
||
that should propagate the "not implemented" error.
|
||
* `connect` (line 727-776) — uses a heuristic: if the driver returns
|
||
`status=associated`, treat as `Connected`, else `Associating`. The real
|
||
state machine has more states (e.g., 4-way handshake, EAPOL).
|
||
|
||
##### 5.4.5 `redbear-iwlwifi` driver
|
||
|
||
Built and registered via `/lib/drivers.d/60-wifi.toml`
|
||
(`redbear-full.toml:228-242`). The driver is invoked through
|
||
`redbear-wifictl`, not directly.
|
||
|
||
#### 5.5 `redbear-netctl` (profile manager + DHCP + DNS)
|
||
|
||
**Location:** `local/recipes/system/redbear-netctl/source/src/main.rs`
|
||
**LoC:** 1,059
|
||
**Implementation language:** Rust, no async.
|
||
|
||
##### 5.5.1 Real implementations
|
||
|
||
* Profile parser (`parse_profile` lines 582-665) — handles `ethernet`/`wifi`
|
||
connections, `dhcp`/`static`/`bounded` IP modes, `wpa2-psk` security.
|
||
* `apply_wifi_profile` (lines 401-447) — writes SSID/security/key to
|
||
`/scheme/wifictl/ifaces/<iface>/...` and triggers `--prepare`,
|
||
`--init-transport`, `--activate-nic`, `--connect`.
|
||
* `apply_profile` for `ethernet` + `dhcp` (lines 247-289) — spawns `dhcpd`
|
||
and polls for an address.
|
||
* `start_profile`, `stop_profile`, `enable_profile`, `disable_profile`
|
||
(lines 195-235).
|
||
* `read_wifictl_value`, `write_wifictl` (lines 449-466) — the scheme I/O
|
||
primitives.
|
||
* 12 unit tests.
|
||
|
||
##### 5.5.2 Stubs / half-impls
|
||
|
||
* `--boot` mode (line 107-112) — reads the active profile name and starts it.
|
||
If no active profile, returns `Ok(())` (a no-op). On a real install, we
|
||
would want this to fall back to scanning and auto-connecting.
|
||
* `apply_profile` for `ethernet` (line 249) — does nothing. Real impl would
|
||
bring up the interface (e.g., set the link up via `ifconfig` or the netstack
|
||
scheme).
|
||
* `static` IP mode (lines 268-279) — writes to `netcfg` scheme directly.
|
||
No validation of the address/gateway format. No DNS search list.
|
||
* DNS writes `resolv/nameserver` (line 277) — single value, no search domain,
|
||
no options (timeout, attempts).
|
||
* No NTP integration. NTP is a hardcoded assumption that the system clock is
|
||
already set (which is the case in QEMU, but not on bare metal).
|
||
* The `dhcp_wait_timeout` is 1 second (line 552), which is too short for
|
||
real DHCP. The default `REDBEAR_DHCPD_WAIT_MS` is 1000ms.
|
||
|
||
#### 5.6 `redbear-info`
|
||
|
||
**Location:** `local/recipes/system/redbear-info/source/src/main.rs`
|
||
**LoC:** 4,704 (one file) + 165 (tui.rs)
|
||
**Built:** yes, on `redbear-mini` and `redbear-full` (cargo build with `tui` feature).
|
||
|
||
This is a TUI/CLI tool for system introspection. It is **not a daemon** — it is
|
||
a per-invocation command. The TUI is feature-gated behind `tui` and is built
|
||
into the binary.
|
||
|
||
The TUI is implemented with `ratatui 0.30 + termion` (per project README) and
|
||
includes 5 tabs (System, Hardware, Network, Integrations, Health).
|
||
|
||
**Stubs in `redbear-info`:** None that I could find. The tool is a real
|
||
implementation. (The 4,704 LoC single file is dense but does not have
|
||
`todo!()` or `unimplemented!()`.)
|
||
|
||
#### 5.7 Cross-cutting network issues
|
||
|
||
1. **No NTP.** Time is set at boot to the bootloader timestamp. A real NTP
|
||
client is missing.
|
||
2. **No Wi-Fi auto-connect on boot** beyond the `--boot` profile. On bare
|
||
metal, the user must run `redbear-netctl --boot` manually.
|
||
3. **No DNS search domain configuration.**
|
||
4. **No IPv6 support.** The netstack uses smoltcp; smoltcp supports IPv6 but
|
||
the Redox netstack daemon may not expose it.
|
||
5. **No firewall.** No iptables/nftables equivalent.
|
||
|
||
---
|
||
|
||
### 6. Initfs vs Rootfs Handoff (CRITICAL)
|
||
|
||
#### 6.1 Initfs daemons
|
||
|
||
`local/sources/base/init.initfs.d/` (full listing):
|
||
|
||
| Service | Purpose | Notes |
|
||
|---|---|---|
|
||
| `00_clock.service` | Time scheme | Required for relibc |
|
||
| `00_logd.service` | Logging | Writes to ramfs |
|
||
| `00_nulld.service` | /dev/null scheme | |
|
||
| `00_randd.service` | Random numbers | |
|
||
| `00_zerod.service` | Zero-byte scheme | |
|
||
| `00_runtime.target` | Group for runtime essentials | |
|
||
| `10_inputd.service` | PS/2 + USB input | Feeds evdev |
|
||
| `10_lived.service` | Live disk driver | |
|
||
| `20_fbbootlogd.service` | Boot log to framebuffer | |
|
||
| `20_fbcond.service` | Console on framebuffer | |
|
||
| `20_graphics.target` | Group for graphics | |
|
||
| `20_vesad.service` | Linear framebuffer handoff | **vesad** for early boot only |
|
||
| `30_acpid.service` | ACPI daemon | |
|
||
| `40_bcm2835-sdhcid.service` | Raspberry Pi SD host | Not used on x86_64 |
|
||
| `40_drivers.target` | Group for drivers | |
|
||
| `40_hwd.service` | Hardware detection | |
|
||
| `40_pcid-spawner-initfs.service` | PCI driver spawner (initfs) | Uses `--initfs` flag |
|
||
| `40_ps2d.service` | PS/2 controller | |
|
||
| `50_rootfs.service` | Mounts the rootfs redoxfs | |
|
||
| `90_initfs.target` | Group for initfs end | |
|
||
| `ramfs@logging.service` | Template: ramfs instance | |
|
||
|
||
The initfs has **no D-Bus, no sessiond, no authd, no greeter, no SDDM, no
|
||
network userland**. The initfs runs:
|
||
|
||
* `vesad` to provide a framebuffer
|
||
* `pcid-spawner --initfs` to spawn PCI drivers
|
||
* `acpid` to read ACPI tables
|
||
* `hwd` to detect hardware
|
||
* `lived` to mount the live ISO (if applicable)
|
||
* `inputd`/`ps2d` to get early input
|
||
* `fbcond`/`fbbootlogd` for the boot framebuffer console
|
||
|
||
The handoff to rootfs is at `50_rootfs.service`: `cmd = "redoxfs"`, args
|
||
`["--uuid", "$REDOXFS_UUID", "file"]`, type `oneshot`.
|
||
|
||
#### 6.2 Rootfs daemons
|
||
|
||
`local/sources/base/init.d/` (rootfs, full listing):
|
||
|
||
| Service | Purpose |
|
||
|---|---|
|
||
| `00_base.target` | Group for basic services |
|
||
| `00_ipcd.service` | Inter-process communication |
|
||
| `00_pcid-spawner.service` | PCI driver spawner (rootfs) |
|
||
| `00_ptyd.service` | Pseudo-terminal |
|
||
| `00_sudo.service` | Privilege escalation |
|
||
| `00_tmp` | /tmp ramfs |
|
||
| `10_dhcpd.service` | DHCP client |
|
||
| `10_net.target` | Group for networking |
|
||
| `10_smolnetd.service` | (renamed to netstack; FIXME in the file) |
|
||
| `20_audiod.service` | Audio multiplexer |
|
||
|
||
The rootfs has **6 + 4 group services**. This is the **minimum** base; the
|
||
redbear-* and other packages add many more via `[[files]]` entries in the
|
||
configs.
|
||
|
||
#### 6.3 Where do D-Bus / session / audio / network start?
|
||
|
||
In the **rootfs**, after the handoff. The ordering is enforced by
|
||
`requires_weak` chains in the service files.
|
||
|
||
| Service | File | Required by |
|
||
|---|---|---|
|
||
| `00_base.target` (rootfs) | `local/sources/base/init.d/00_base.target` | All others |
|
||
| `00_ipcd.service` | `local/sources/base/init.d/00_ipcd.service` | `00_base.target` |
|
||
| `00_pcid-spawner.service` | `local/sources/base/init.d/00_pcid-spawner.service` | `00_base.target` |
|
||
| `00_ptyd.service` | `local/sources/base/init.d/00_ptyd.service` | `00_base.target` |
|
||
| `00_sudo.service` | `local/sources/base/init.d/00_sudo.service` | (rootfs default) |
|
||
| `10_dhcpd.service` | `local/sources/base/init.d/10_dhcpd.service` | `10_smolnetd.service` |
|
||
| `10_smolnetd.service` | `local/sources/base/init.d/10_smolnetd.service` | `00_pcid-spawner.service` |
|
||
| `20_audiod.service` | `local/sources/base/init.d/20_audiod.service` | `00_base.target` |
|
||
| `12_dbus.service` | `redbear-mini.toml:373-385` (overrides nothing in base) | `12_boot-late.target` |
|
||
| `13_redbear-sessiond.service` | `redbear-mini.toml:400-411` | `12_dbus.service` |
|
||
| `13_seatd.service` | `redbear-mini.toml:387-396` (no-op) | (no requires) |
|
||
| `13_seatd.service` | `redbear-full.toml:329-343` (real) | `12_dbus.service`, `13_redbear-sessiond.service` |
|
||
| `11_redbear-authd.service` | `redbear-full.toml:433-446` | `12_dbus.service` |
|
||
| `12_sddm.service` | `redbear-full.toml:448-467` | `00_driver-manager`, `10_redox-drm`, `10_evdevd`, `12_dbus`, `13_redbear-sessiond`, `13_seatd`, `11_redbear-authd` |
|
||
| `11_wifictl.service` | `redbear-mini.toml:357-370` | `12_boot-late.target`, `00_driver-manager.service` |
|
||
| `13_redbear-keymapd.service` | `redbear-full.toml:349-361` | `10_evdevd.service` |
|
||
| `13_redbear-ime.service` | `redbear-full.toml:363-375` | `10_evdevd.service` |
|
||
| `13_redbear-accessibility.service` | `redbear-full.toml:377-389` | `10_evdevd.service` |
|
||
| `14_redbear-upower.service` | `redbear-full.toml:391-403` | `12_dbus.service` |
|
||
| `14_redbear-udisks.service` | `redbear-full.toml:405-417` | `12_dbus.service` |
|
||
| `14_redbear-polkit.service` | `redbear-full.toml:419-431` | `12_dbus.service` |
|
||
| `00_firmware-loader.service` | `redbear-full.toml:244-256` | `05_boot-essential.target` |
|
||
| `05_boot-essential.target` | `redbear-full.toml:258-266` | `04_drivers.target` |
|
||
| `13_iommu.service` | `redbear-full.toml:268-281` | `05_boot-essential.target`, `00_acpid.service` |
|
||
| `10_redox-drm.service` | `redbear-full.toml:283-297` | `05_boot-essential.target`, `00_driver-manager.service` |
|
||
|
||
#### 6.4 Initfs vs rootfs overlap
|
||
|
||
The `vesad` daemon runs in initfs only (`init.initfs.d/20_vesad.service`).
|
||
**The rootfs does not start vesad again.** This is correct per the
|
||
"NO VESA POLICY" in the project AGENTS.md.
|
||
|
||
`acpid` runs in initfs (`init.initfs.d/30_acpid.service`) AND is referenced
|
||
by `redbear-full.toml:13_iommu.service` (which `requires_weak =
|
||
["05_boot-essential.target", "00_acpid.service"]`). The `00_acpid.service`
|
||
is the initfs one. The `requires_weak` says "wait until initfs acpid is up."
|
||
This is correct but couples the rootfs services to the initfs service names.
|
||
**Stale code risk:** if `00_acpid.service` is renamed in initfs, the rootfs
|
||
`requires_weak` will silently fail.
|
||
|
||
`pcid-spawner` runs in initfs (`40_pcid-spawner-initfs.service`) with
|
||
`args = ["--initfs"]`. The rootfs runs `00_pcid-spawner.service` without the
|
||
flag. This is a clean handoff: the initfs spawns the early drivers (vesad,
|
||
ps2d, lived), then the rootfs takes over for the rest.
|
||
|
||
`dhcpd` runs only in rootfs (no initfs dhcpd). This is correct.
|
||
|
||
`audiod` runs only in rootfs. There is no initfs audio. This is correct.
|
||
|
||
#### 6.5 Handoff issues
|
||
|
||
1. **No explicit handoff notification.** The initfs finishes its work
|
||
(vesad, pcid-spawner --initfs, hwd, acpid), then `50_rootfs.service` runs
|
||
`redoxfs` to mount the rootfs. There is no synchronization between the
|
||
initfs pcid-spawner finishing and the rootfs pcid-spawner starting —
|
||
`requires_weak` is **not** used here. The rootfs pcid-spawner may try
|
||
to spawn drivers that the initfs pcid-spawner is still spawning.
|
||
2. **`driver-manager` is referenced in `redbear-full.toml:454` (sddm
|
||
requires `00_driver-manager.service`) but the service file is provided by
|
||
`redbear-device-services.toml`** which is included by `redbear-mini.toml:12`.
|
||
3. **`10_evdevd.service` is referenced by `12_sddm.service` (line 456) but
|
||
the file is in `local/recipes/system/evdevd/source/init.d/10_evdevd.service`**
|
||
and the `redbear-mini.toml:343-355` already installs it. So it is present.
|
||
4. **`10_redox-drm.service` has an unusual one-liner:**
|
||
`redbear-full.toml:294-296`:
|
||
```
|
||
cmd = "/usr/bin/sh"
|
||
args = ["-c", "if ! head -c 1 /scheme/drm/card0 >/dev/null 2>&1; then exec /usr/bin/redox-drm; fi; echo 'scheme:drm already registered, skipping'"]
|
||
```
|
||
This is a **race-condition workaround**. The
|
||
`redbear-greeter-compositor` script (line 39-46) has an explicit comment:
|
||
"On Redox, stat and test -e are unreliable for scheme paths" and uses
|
||
`( exec 3<"/scheme/drm/card0" )` instead. The init service uses
|
||
`head -c 1 /scheme/drm/card0` which **will block** waiting for a request
|
||
response on the DRM scheme (per the comment in
|
||
`redbear-greeter-compositor:40-41`). This is a known-bad pattern; the
|
||
correct pattern is the `exec 3<...` one. **Stale code in `redbear-full.toml`.**
|
||
|
||
#### 6.6 Stale code (initfs / rootfs handoff)
|
||
|
||
* `local/sources/base/init.initfs.d/10_smolnetd.service:1` — `# FIXME rename to
|
||
10_netstack.service`. The file is still named 10_smolnetd.
|
||
* `redbear-full.toml:295` — `head -c 1 /scheme/drm/card0` will block; should
|
||
use the open-as-probe pattern.
|
||
|
||
|
||
---
|
||
|
||
## Cross-Cutting Issues
|
||
|
||
### Service Activation Order (for KDE to work)
|
||
|
||
Required rootfs order (current vs needed):
|
||
|
||
| # | Service | Current status | Built? | Started? | Comments |
|
||
|---|---|---|---|---|---|
|
||
| 1 | `00_base.target` | ✅ in init.d | n/a | yes | Foundation |
|
||
| 2 | `00_logd` (initfs) | ✅ in init.initfs.d | yes | yes (initfs) | Survives handoff |
|
||
| 3 | `00_ipcd` | ✅ in init.d | yes | yes | |
|
||
| 4 | `00_pcid-spawner` (rootfs) | ✅ in init.d | yes | yes | |
|
||
| 5 | `00_driver-manager` | ✅ in `redbear-device-services.toml` | yes | yes | |
|
||
| 6 | `00_firmware-loader` | ✅ `redbear-full.toml:244-256` | yes | yes | |
|
||
| 7 | `10_redox-drm` | ✅ `redbear-full.toml:283-297` | yes | yes | |
|
||
| 8 | `10_evdevd` | ✅ in `redbear-mini.toml` (inherits) | yes | yes | |
|
||
| 9 | `10_smolnetd` (renamed to `10_netstack`) | ✅ in `redbear-mini.toml:119-131` | yes | yes | |
|
||
| 10 | `10_dhcpd` | ✅ in `redbear-mini.toml:133-146` | yes | yes | |
|
||
| 11 | `12_dbus` | ✅ `redbear-full.toml:299-313` | yes | yes | |
|
||
| 12 | `13_redbear-sessiond` | ✅ `redbear-full.toml:315-327` | yes | yes | |
|
||
| 13 | `13_seatd` | ✅ `redbear-full.toml:329-343` | yes | yes | But not used (see §3) |
|
||
| 14 | `11_redbear-authd` | ✅ `redbear-full.toml:433-446` | yes | yes | |
|
||
| 15 | `13_redbear-keymapd` | ✅ `redbear-full.toml:349-361` | yes | yes | |
|
||
| 16 | `13_redbear-ime` | ✅ `redbear-full.toml:363-375` | yes | yes | |
|
||
| 17 | `13_redbear-accessibility` | ✅ `redbear-full.toml:377-389` | yes | yes | |
|
||
| 18 | `14_redbear-upower` | ✅ `redbear-full.toml:391-403` | yes | yes | |
|
||
| 19 | `14_redbear-udisks` | ✅ `redbear-full.toml:405-417` | yes | yes | |
|
||
| 20 | `14_redbear-polkit` | ✅ `redbear-full.toml:419-431` | yes | yes | But see §1.9 polkit caller-UID defect |
|
||
| 21 | `12_sddm` | ✅ `redbear-full.toml:448-467` | yes | yes | PAM not wired |
|
||
| 22 | `pipewire` (NEW) | ❌ not present | NO | NO | **Required for audio** |
|
||
| 23 | `wireplumber` (NEW) | ❌ not present | NO | NO | **Required for audio** |
|
||
| 24 | `redbear-notifications` (session) | ❌ not started | yes | NO | **Required for KDE notifications** |
|
||
| 25 | `redbear-statusnotifierwatcher` | ❌ not started | yes | NO | **Required for KDE tray** |
|
||
| 26 | `redbear-firmware` | ✅ `redbear-full.toml:52-53` | yes | yes | |
|
||
|
||
### D-Bus activation
|
||
|
||
For KDE to start, D-Bus must activate:
|
||
|
||
* `org.kde.KWin` — missing
|
||
* `org.kde.plasma` — missing
|
||
* `org.kde.kded6` — present (kded6-offscreen workaround)
|
||
* `org.kde.kglobalacceld` — present (file exists)
|
||
* `org.freedesktop.Notifications` — present (file exists)
|
||
* `org.freedesktop.StatusNotifierWatcher` — missing (no service file)
|
||
|
||
Are these `.service` files in `/usr/share/dbus-1/system-services/` or
|
||
`~/.local/share/dbus-1/services/`? **None of the missing ones are in either
|
||
location.**
|
||
|
||
### Polkit / Authentication
|
||
|
||
* Polkit daemon: `redbear-polkit` (241 LoC). Service file: yes. Started: yes.
|
||
* Policy file: `/etc/polkit-1/policy.toml` (12 lines, 8 actions, all uid-0
|
||
authorized). Real polkit expects `*.policy` XML files with full action
|
||
descriptions and a JavaScript .rules authority. **The Red Bear polkit is a
|
||
flat-file UID lookup.** KDE's `polkit-kde-agent-1` will query polkit and get
|
||
a correct response for root-uid; for user-uid 1000, the policy says
|
||
`org.freedesktop.login1.power-off = 0, 1000` so the user can shut down.
|
||
This is **functional** for the common actions.
|
||
* PAM: not present. SDDM expects libpam. **PAM is the critical missing
|
||
piece for SDDM to authenticate a user.**
|
||
|
||
### PipeWire / WirePlumber
|
||
|
||
* PipeWire: not present. **Required for KDE audio.**
|
||
* WirePlumber: not present. **Required for KDE audio policy.**
|
||
|
||
### Other missing wirings (cross-cutting)
|
||
|
||
1. **No `redbear-notifications.service`** in `redbear-full.toml` →
|
||
`local/recipes/system/redbear-notifications/source/init.d/` is empty.
|
||
The daemon is built but not started.
|
||
2. **No `redbear-statusnotifierwatcher.service`** anywhere.
|
||
3. **No `/etc/machine-id`** generated by any init step. `dbus-daemon` requires
|
||
`/etc/machine-id` to start. If it's not present, the daemon may fail to
|
||
start. (This is provided by systemd in mainstream distros; on Redox, it
|
||
should be generated at first boot.)
|
||
4. **No `/var/lib/dbus/machine-id`** either.
|
||
5. **No NetworkManager or netctl-ifcfg integration with D-Bus.** The
|
||
`redbear-wifictl/source/src/dbus_nm.rs` (47 LoC) only defines
|
||
`register_nm_interface` which is gated on `cfg(target_os = "redox")` and
|
||
is a stub.
|
||
|
||
---
|
||
|
||
## Implementation Roadmap
|
||
|
||
### Phase 1: Unblock D-Bus + session activation (1–2 weeks)
|
||
|
||
1. Add a `redbear-notifications.service` to `redbear-full.toml` that starts
|
||
on the **session bus**. The session bus itself must be started by
|
||
`redbear-session-launch` (already partially done via `dbus-run-session`).
|
||
Remove the duplicate `dbus-launch` in `redbear-kde-session:152`.
|
||
2. Add a `redbear-statusnotifierwatcher.service` to `redbear-full.toml`
|
||
(session bus).
|
||
3. Generate `/etc/machine-id` at first boot (or at install time).
|
||
4. Add `org.kde.kglobalacceld.service`, `org.kde.KWin.service`,
|
||
`org.kde.plasmashell.service` to `redbear-dbus-services`.
|
||
5. Fix the `org.freedesktop.UPower.service` `SystemdService=redbear-polkit.service`
|
||
copy-paste bug.
|
||
6. Add `dbus-update-activation-environment` to `redbear-session-launch`
|
||
(currently only in `redbear-kde-session`).
|
||
|
||
Estimated LoC: ~300.
|
||
|
||
### Phase 2: Wire Session Management (2–3 weeks)
|
||
|
||
1. Implement `redbear-sessiond::kill_session`, `kill_user`, `power_off`,
|
||
`reboot`, `suspend` (real shutdown, real kill, no more "no-op" logs).
|
||
2. Implement `redbear-sessiond::IdleSinceHint`, `IdleSinceHintMonotonic`
|
||
with real timestamps.
|
||
3. Implement `redbear-sessiond::HandleLidSwitch` with real ACPI events
|
||
from `acpid`.
|
||
4. Implement `redbear-polkit::CheckAuthorization` with caller-UID extraction
|
||
(use zbus connection metadata).
|
||
5. Implement `redbear-sessiond::Can*` methods to return real values
|
||
(check binary existence, not hardcoded "na").
|
||
6. Fix `device_map::dev_major` for Redox-native `rdev()`.
|
||
7. Fix `redbear-session-launch::apply_groups` to actually use the
|
||
supplementary-groups syscalls.
|
||
8. Fix `redbear-authd::launch_session` to support more than just
|
||
`kde-wayland`.
|
||
9. Add a `redbear-passwd` service for password management (currently
|
||
only a library, no binary).
|
||
|
||
Estimated LoC: ~600.
|
||
|
||
### Phase 3: Wire Audio (4–6 weeks)
|
||
|
||
1. Port PipeWire to Redox (or accept that audio in KDE is broken).
|
||
2. Port WirePlumber to Redox.
|
||
3. Create `local/recipes/system/pipewire/recipe.toml` and
|
||
`local/recipes/system/wireplumber/recipe.toml`.
|
||
4. Add a `pipewire.service` to `redbear-full.toml` (session bus, started
|
||
by `redbear-kde-session`).
|
||
5. Add a `wireplumber.service` to `redbear-full.toml` (session bus).
|
||
6. Set `PIPEWIRE_REMOTE` and `PIPEWIRE_RUNTIME_DIR` in
|
||
`redbear-session-launch`.
|
||
7. Update `redbear-kde-session` to start pipewire and wireplumber.
|
||
|
||
Estimated LoC: ~2,000 (mostly upstream porting).
|
||
|
||
### Phase 4: Wire Network enhancements (1–2 weeks)
|
||
|
||
1. Remove `StubBackend` from `redbear-wifictl` (or gate it on `cfg(test)`).
|
||
2. Port NTP daemon (`chrony` or `ntpd-rs`).
|
||
3. Add NTP service to `redbear-full.toml`.
|
||
4. Multi-DNS support in `redbear-netctl`.
|
||
5. Wi-Fi auto-connect on boot.
|
||
|
||
Estimated LoC: ~800.
|
||
|
||
### Phase 5: PAM and SDDM integration (2–3 weeks)
|
||
|
||
1. Port a minimal `libpam` to Redox (or use a stub that calls
|
||
`redbear-authd` over its Unix socket).
|
||
2. Add `/etc/pam.d/sddm` config.
|
||
3. Verify SDDM authenticates through `redbear-authd`.
|
||
4. Verify the session bus is started by SDDM and propagated to the user
|
||
session.
|
||
|
||
Estimated LoC: ~500.
|
||
|
||
### Phase 6: Remove dead / stale code (1 week)
|
||
|
||
1. Remove the `kded6-offscreen` shell wrapper; integrate the QPA override
|
||
into the `kded6.service` file directly (already done; the wrapper is
|
||
redundant).
|
||
2. Remove the duplicate `dbus-launch` call in `redbear-kde-session`.
|
||
3. Remove the `redbear-greeter-compositor` / `redbear-kde-session`
|
||
shell wrappers and replace with a Rust binary
|
||
(`redbear-session-orchestrator`).
|
||
4. Remove the `StubBackend` from `redbear-wifictl`.
|
||
5. Replace `redbear-full.toml:294-296` `head -c 1` DRM probe with
|
||
`exec 3<...` pattern.
|
||
6. Remove `redbear-firmware` recipe's `linux-firmware` clone (use
|
||
`fetch-firmware.sh` per project AGENTS.md).
|
||
|
||
Estimated LoC: ~300 net (remove old, add replacement).
|
||
|
||
---
|
||
|
||
## Testing Strategy
|
||
|
||
### Unit tests (already present)
|
||
|
||
* `redbear-sessiond`: ~30 unit tests in `mod tests` blocks across
|
||
`manager.rs`, `session.rs`, `seat.rs`, `control.rs`, `device_map.rs`.
|
||
* `redbear-authd`: 12 unit tests in `main.rs:515-718`.
|
||
* `redbear-session-launch`: 9 unit tests in `main.rs:404-627`.
|
||
* `redbear-greeter`: 10 unit tests in `main.rs:503-655`.
|
||
* `redbear-netctl`: 12 unit tests in `main.rs:667-1032`.
|
||
* `redbear-wifictl`: 6 unit tests in `main.rs:130-196`.
|
||
* `redbear-info`: not yet read in full but the test count is expected to
|
||
be > 30 given the 4,704 LoC.
|
||
|
||
### Integration tests (missing)
|
||
|
||
* No integration test that boots `redbear-full` and checks
|
||
`dbus-send --system --dest=org.freedesktop.login1 /org/freedesktop/login1
|
||
org.freedesktop.login1.Manager.ListSeats`.
|
||
* No integration test that starts `redbear-authd` and posts an
|
||
`Authenticate` request.
|
||
* No integration test that runs `redbear-greeterd` end-to-end.
|
||
|
||
### Validation commands
|
||
|
||
* `./local/scripts/test-greeter-qemu.sh --check` — exists per
|
||
`local/AGENTS.md` line 84.
|
||
* `./local/scripts/test-phase5-network-qemu.sh --check` — exists.
|
||
* `./local/scripts/test-phase6-kde-qemu.sh --check` — exists.
|
||
* `redbear-greeter-check`, `redbear-greeter-check --invalid root wrong` —
|
||
expected to be installed in the image.
|
||
|
||
---
|
||
|
||
## Risk Assessment
|
||
|
||
### Impact of shipping as-is
|
||
|
||
If we ship `redbear-full` today:
|
||
|
||
* The system will boot.
|
||
* The user will see a framebuffer console (initfs vesad).
|
||
* pcid-spawner will run, drivers will load.
|
||
* The D-Bus system bus will start.
|
||
* `redbear-sessiond`, `seatd`, `redbear-authd` will register.
|
||
* `redbear-upower`, `redbear-udisks`, `redbear-polkit` will register.
|
||
* SDDM will attempt to start. It will try to load `libpam`. **It will fail.**
|
||
* If SDDM fails, the user will be dropped to a text console on VT 2
|
||
(per the `30_console.service` in `redbear-mini.toml`).
|
||
* Network (`dhcpd`, `netstack`, `wifictl`) will be running.
|
||
* The user can run `redbear-netctl --boot` to connect.
|
||
* The user can run `redbear-info` to see system status.
|
||
|
||
**The desktop will not work.** This is the critical gap.
|
||
|
||
### Minimum to make SDDM display a login screen
|
||
|
||
1. A Red Bear PAM module (or relibc libpam) that:
|
||
- Reads `/etc/pam.d/sddm` config.
|
||
- For `auth` calls `redbear-authd` over Unix socket.
|
||
- For `session` opens a `redbear-session-launch` process.
|
||
2. SDDM greeter binary (`sddm-greeter`) — must be built and installed.
|
||
3. SDDM theme (`mayagrid` is referenced in `redbear-full.toml:574-577`).
|
||
4. `redbear-greeter-compositor` shell wrapper replaced with a real
|
||
Wayland-capable compositor or with SDDM's own compositor helper.
|
||
|
||
### Minimum to make KDE Plasma start after login
|
||
|
||
1. All of the above, plus:
|
||
2. PipeWire + WirePlumber.
|
||
3. The session-bus must be started, with `DBUS_SESSION_BUS_ADDRESS`
|
||
propagated to `kwin_wayland`, `plasmashell`, etc.
|
||
4. The `redbear-kde-session` shell wrapper must be called by SDDM after
|
||
auth, not by `redbear-greeter` (because we are not using redbear-greeter).
|
||
5. The Qt6 Wayland `null+8` crash must be fixed in the Qt6 port.
|
||
|
||
|
||
---
|
||
|
||
## Appendix A: Grep Results
|
||
|
||
### A.1 `todo!()` and `unimplemented!()` in `local/recipes/system/`
|
||
|
||
```
|
||
$ grep -rn 'todo!()\|unimplemented!()' local/recipes/system/ 2>/dev/null | grep -v /target/
|
||
(no matches)
|
||
```
|
||
|
||
**Zero `todo!()` or `unimplemented!()` in the chain.** This is good.
|
||
|
||
### A.2 `#TODO` in `local/recipes/system/` recipe.toml
|
||
|
||
```
|
||
$ grep -rn '#TODO' local/recipes/system/ 2>/dev/null
|
||
local/recipes/system/dbus/recipe.toml:1:#TODO: validate runtime (dbus-daemon --system + dbus-launch for session bus)
|
||
local/recipes/system/redbear-polkit/recipe.toml:1:#TODO: redbear-polkit — org.freedesktop.PolicyKit1 daemon. UID-based authorization via /etc/polkit-1/policy.toml. Root always authorized.
|
||
local/recipes/system/redbear-upower/recipe.toml:1:#TODO: redbear-upower — minimal org.freedesktop.UPower daemon. Enumerates power state from scheme:acpi.
|
||
local/recipes/system/redbear-udisks/recipe.toml:1:#TODO: redbear-udisks — minimal org.freedesktop.UDisks2 daemon. Enumerates block devices from scheme: filesystem.
|
||
local/recipes/system/redbear-notifications/recipe.toml:1:#TODO: redbear-notifications — minimal org.freedesktop.Notifications daemon. Logs notifications to stderr until a display server integration exists.
|
||
```
|
||
|
||
5 recipes have a `#TODO` first-line. All 5 are documentation notes, not blocking
|
||
issues, but they signal that the implementations are intentionally minimal.
|
||
|
||
### A.3 Stubs in `local/recipes/system/` source
|
||
|
||
* `redbear-wifictl/src/backend.rs:140-245` — `StubBackend` is a stub.
|
||
* `redbear-wifictl/src/backend.rs:247-320` — `NoDeviceBackend` is a no-op
|
||
error-returning backend (not a stub, but a deliberate "no device" state).
|
||
* `redbear-sessiond/src/manager.rs:143-169` — 7 `can_*` methods return `"na"`.
|
||
* `redbear-sessiond/src/manager.rs:171-187` — `power_off`, `reboot`,
|
||
`suspend` log only.
|
||
* `redbear-sessiond/src/manager.rs:322-342` — `kill_session`, `kill_user`
|
||
log "no-op".
|
||
* `redbear-sessiond/src/session.rs:206-212` — `kill` logs "no-op".
|
||
* `redbear-polkit/src/main.rs:144` — `CheckAuthorization` always queries
|
||
with uid 0 (security defect).
|
||
* `redbear-notifications/src/main.rs` — `Notify` only `eprintln!`s, does
|
||
not display.
|
||
* `redbear-statusnotifierwatcher/src/main.rs` — only tracks items/hosts in
|
||
memory, does not bridge to KDE's tray (KDE does this on its own).
|
||
* `redbear-udisks/src/interfaces.rs:108-115` — `SupportedFilesystems` and
|
||
`SupportedEncryptionTypes` return empty vec.
|
||
* `redbear-udisks/src/interfaces.rs:137-138` — `Symlinks` returns empty vec.
|
||
|
||
### A.4 Service files in `local/recipes/system/*/source/init.d/`
|
||
|
||
```
|
||
$ find local/recipes/system -name '*.service' -path '*/init.d/*'
|
||
local/recipes/system/evdevd/source/init.d/10_evdevd.service
|
||
local/recipes/system/redbear-keymapd/source/init.d/13_redbear-keymapd.service
|
||
local/recipes/system/redbear-polkit/source/init.d/20_polkit.service
|
||
```
|
||
|
||
3 recipes ship init.d service files. The rest rely on `redbear-mini.toml` or
|
||
`redbear-full.toml` to install the service file via `[[files]]`.
|
||
|
||
### A.5 Recipes with no `recipe.toml`
|
||
|
||
*None.* All 47 recipes under `local/recipes/system/` have a `recipe.toml`.
|
||
|
||
### A.6 Recipes whose binary is built but not started in any config
|
||
|
||
* `local/recipes/system/redbear-notifications` — built, but no service file in
|
||
any config; **never started**.
|
||
* `local/recipes/system/redbear-statusnotifierwatcher` — built, but no
|
||
service file anywhere; **never started**.
|
||
* `local/recipes/system/redbear-passwd` — a library (lib.rs), not a binary.
|
||
The recipe declares `[lib]` only, no `[[bin]]`. So this is a
|
||
"library" recipe with no binary, no service.
|
||
* `local/recipes/system/redbear-meta` — meta package; depends on other
|
||
recipes. The `script` in `recipe.toml` just writes a README to the
|
||
sysroot. There is no binary to start.
|
||
|
||
### A.7 D-Bus service / policy files in `redbear-dbus-services`
|
||
|
||
```
|
||
session.d/
|
||
org.redbear.session.conf (16 lines, wildcard allow org.kde.*)
|
||
session-services/
|
||
org.kde.kded6.service (5 lines, forces offscreen)
|
||
org.kde.kglobalaccel.service (3 lines)
|
||
org.freedesktop.Notifications.service (3 lines)
|
||
system.d/
|
||
org.freedesktop.login1.conf (23 lines)
|
||
org.freedesktop.PolicyKit1.conf (11 lines)
|
||
org.freedesktop.UDisks2.conf (11 lines)
|
||
org.freedesktop.UPower.conf (11 lines)
|
||
system-services/
|
||
org.freedesktop.login1.service (4 lines, /usr/bin/redbear-sessiond)
|
||
org.freedesktop.PolicyKit1.service (5 lines, SystemdService=redbear-polkit.service)
|
||
org.freedesktop.UPower.service (5 lines, SystemdService=redbear-polkit.service) [STALE]
|
||
org.freedesktop.UDisks2.service (5 lines)
|
||
kded6-offscreen (3 lines, shell wrapper)
|
||
```
|
||
|
||
Total: 11 files, 102 LoC.
|
||
|
||
### A.8 Init.d service file ownership
|
||
|
||
* `local/sources/base/init.initfs.d/` — 21 files, all owned by Redox.
|
||
* `local/sources/base/init.d/` — 10 files (9 service + 1 target), all
|
||
owned by Redox.
|
||
* `local/recipes/system/evdevd/source/init.d/10_evdevd.service` — 1 file,
|
||
owned by Red Bear.
|
||
* `local/recipes/system/redbear-keymapd/source/init.d/13_redbear-keymapd.service` —
|
||
1 file, owned by Red Bear.
|
||
* `local/recipes/system/redbear-polkit/source/init.d/20_polkit.service` —
|
||
1 file, owned by Red Bear.
|
||
|
||
**3 Red Bear init.d service files; the rest are inlined as `[[files]]` in
|
||
`redbear-mini.toml` or `redbear-full.toml`.** This is a code organization
|
||
choice — the inlined approach is more visible in the config but less
|
||
reusable.
|
||
|
||
---
|
||
|
||
## Appendix B: File-by-file Line Counts
|
||
|
||
### B.1 Session Management
|
||
|
||
| File | LoC | Notes |
|
||
|---|---|---|
|
||
| `local/recipes/system/redbear-sessiond/source/src/main.rs` | 188 | Daemon entry point |
|
||
| `local/recipes/system/redbear-sessiond/source/src/manager.rs` | 642 | LoginManager interface |
|
||
| `local/recipes/system/redbear-sessiond/source/src/session.rs` | 450 | LoginSession interface |
|
||
| `local/recipes/system/redbear-sessiond/source/src/seat.rs` | 147 | LoginSeat interface |
|
||
| `local/recipes/system/redbear-sessiond/source/src/control.rs` | 221 | Control socket (authd → sessiond handoff) |
|
||
| `local/recipes/system/redbear-sessiond/source/src/device_map.rs` | 267 | DRM/input device map |
|
||
| `local/recipes/system/redbear-sessiond/source/src/runtime_state.rs` | 54 | Shared state |
|
||
| `local/recipes/system/redbear-sessiond/source/src/acpi_watcher.rs` | 48 | Stub signature; impl in patch |
|
||
| **sessiond total** | **2,017** | |
|
||
| `local/recipes/system/redbear-authd/source/src/main.rs` | 719 | Full Unix-socket protocol |
|
||
| `local/recipes/system/redbear-session-launch/source/src/main.rs` | 628 | setuid session launcher |
|
||
| `local/recipes/system/redbear-greeter/source/src/main.rs` | 656 | Greeter daemon |
|
||
| `local/recipes/system/redbear-greeter/source/redbear-greeter-compositor` | 4,310 bytes | Bash wrapper |
|
||
| `local/recipes/system/redbear-greeter/source/redbear-kde-session` | 8,936 bytes | Bash wrapper |
|
||
| **Session management total Rust LoC** | **4,020** | **+13,246 bytes of Bash** |
|
||
|
||
### B.2 D-Bus services
|
||
|
||
| File | LoC | Notes |
|
||
|---|---|---|
|
||
| `local/recipes/system/dbus/recipe.toml` | 25 | With `#TODO` |
|
||
| `local/recipes/system/dbus/source/dbus/*.c` (unpacked) | ~340,000 | Upstream C, not in our audit scope |
|
||
| `local/recipes/system/dbus/redox.patch` | 24 | epoll + socketpair |
|
||
| `local/recipes/system/redbear-dbus-services/source/**/*` | 102 | Service + policy files |
|
||
| `local/recipes/system/redbear-dbus-services/recipe.toml` | 16 | Custom template |
|
||
| `local/recipes/system/redbear-polkit/source/src/main.rs` | 241 | PolicyKit1 service |
|
||
| `local/recipes/system/redbear-upower/source/src/main.rs` | 622 | UPower service |
|
||
| `local/recipes/system/redbear-udisks/source/src/main.rs` | 174 | UDisks2 service |
|
||
| `local/recipes/system/redbear-udisks/source/src/interfaces.rs` | 218 | D-Bus interface impls |
|
||
| `local/recipes/system/redbear-udisks/source/src/inventory.rs` | 281 | Disk inventory |
|
||
| `local/recipes/system/redbear-notifications/source/src/main.rs` | 198 | Notification service |
|
||
| `local/recipes/system/redbear-statusnotifierwatcher/source/src/main.rs` | 168 | Status notifier watcher |
|
||
| **D-Bus services total Rust LoC (Red Bear)** | **1,902** | |
|
||
|
||
### B.3 Audio
|
||
|
||
| File | LoC | Notes |
|
||
|---|---|---|
|
||
| `local/sources/base/audiod/src/main.rs` | 100 | audiod daemon |
|
||
| `local/sources/base/audiod/src/scheme.rs` | 177 | Audio scheme |
|
||
| `local/recipes/system/redbear-usbaudiod/source/src/main.rs` | (not surveyed) | USB audio device driver |
|
||
| **Audio total LoC (Red Bear)** | **277** | PipeWire/WirePlumber absent |
|
||
|
||
### B.4 Network
|
||
|
||
| File | LoC | Notes |
|
||
|---|---|---|
|
||
| `local/sources/base/netstack/src/main.rs` | 198 | netstack daemon |
|
||
| `local/sources/base/netstack/src/buffer_pool.rs` | 96 | smoltcp buffer pool |
|
||
| `local/sources/base/netstack/src/error.rs` | 55 | |
|
||
| `local/sources/base/netstack/src/logger.rs` | 17 | |
|
||
| `local/sources/base/netstack/src/port_set.rs` | 62 | |
|
||
| `local/sources/base/dhcpd/src/main.rs` | 497 | DHCP client |
|
||
| `local/sources/base/dhcpd/src/dhcp/mod.rs` | (not surveyed) | DHCP protocol |
|
||
| `local/recipes/system/redbear-netctl/source/src/main.rs` | 1,059 | Profile manager |
|
||
| `local/recipes/system/redbear-wifictl/source/src/main.rs` | 487 | Wi-Fi control |
|
||
| `local/recipes/system/redbear-wifictl/source/src/backend.rs` | 1,509 | Wi-Fi backends |
|
||
| `local/recipes/system/redbear-wifictl/source/src/dbus_nm.rs` | 47 | NetworkManager D-Bus stub |
|
||
| `local/recipes/system/redbear-wifictl/source/src/scheme.rs` | 743 | Wi-Fi scheme |
|
||
| `local/recipes/system/redbear-info/source/src/main.rs` | 4,704 | System info CLI |
|
||
| `local/recipes/system/redbear-info/source/src/tui.rs` | 165 | TUI |
|
||
| **Network + info total Rust LoC** | **9,638** | |
|
||
|
||
### B.5 seatd
|
||
|
||
| File | LoC | Notes |
|
||
|---|---|---|
|
||
| `local/recipes/system/seatd/source/seatd/server.c` | 171 | |
|
||
| `local/recipes/system/seatd/source/seatd/client.c` | 528 | |
|
||
| `local/recipes/system/seatd/source/seatd/poller.c` | 327 | |
|
||
| `local/recipes/system/seatd/source/seatd/seat.c` | 757 | |
|
||
| `local/recipes/system/seatd/source/seatd/seatd.c` | 220 | |
|
||
| `local/recipes/system/seatd/source/common/*.c` | (not surveyed) | Linux-only backends |
|
||
| `local/recipes/system/seatd/source/libseat/*.c` | (not surveyed) | libseat client lib |
|
||
| **seatd total LoC** | **2,003+** | Upstream C |
|
||
|
||
### B.6 Initfs vs rootfs service files
|
||
|
||
* `local/sources/base/init.initfs.d/` — 21 files
|
||
* `local/sources/base/init.d/` — 10 files
|
||
* `redbear-mini.toml` — 23 `[[files]]` entries for service files
|
||
* `redbear-full.toml` — 25 `[[files]]` entries for service files
|
||
|
||
### B.7 Grand total
|
||
|
||
| Subsystem | LoC |
|
||
|---|---|
|
||
| Session management (Rust) | 4,020 |
|
||
| Session management (Bash) | 13,246 bytes |
|
||
| D-Bus services (Rust, Red Bear) | 1,902 |
|
||
| D-Bus services (upstream C) | ~340,000 (out of scope) |
|
||
| Audio (Rust, Red Bear) | 277 |
|
||
| Network (Rust, Red Bear) | 9,638 |
|
||
| seatd (upstream C) | 2,003+ |
|
||
| **Total Red Bear Rust LoC in the chain** | **~15,840** |
|
||
|
||
---
|
||
|
||
## Closing Notes
|
||
|
||
The Red Bear OS desktop-services chain is **substantially implemented** at the
|
||
D-Bus / sessiond / authd level. The Rust code is well-tested, well-structured,
|
||
and the D-Bus interfaces closely follow the freedesktop.org specifications.
|
||
|
||
The critical gaps are:
|
||
|
||
1. **No PipeWire / WirePlumber** (audio is broken in KDE).
|
||
2. **No PAM** (SDDM cannot authenticate).
|
||
3. **No session-bus user services** (notifications, status notifier, KDE
|
||
services are not auto-started).
|
||
4. **`StubBackend` in `redbear-wifictl`** is a real stub.
|
||
5. **KDE session wrapper has known QPA / Wayland crash** (`null+8`).
|
||
6. **`polkit` caller-UID is hardcoded to 0** (security defect, but
|
||
currently masked by the `org.kde.*` wildcard policy).
|
||
|
||
**Estimated total LoC to fix:** ~4,500 LoC across 6 phases.
|
||
**Estimated total time:** 8–12 weeks with 1–2 developers.
|
||
|
||
The chain is buildable and the static review is solid. The dynamic review
|
||
(runtime in QEMU, then bare metal) is the next critical step. Many of the
|
||
"real" implementations may surface runtime defects that this static review
|
||
cannot catch — particularly around the seatd ↔ KWin ↔ /scheme/drm/card0
|
||
integration, the Qt6 Wayland `null+8` crash, and the PAM/Sddm/authd
|
||
connection.
|